├── .formatter.exs
├── .github
└── workflows
│ └── ci.yaml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bench
├── snapshots
│ ├── 2016-03-30_11-52-51.snapshot
│ └── 2019-02-27_18-33-20.snapshot
└── vector_bench.exs
├── config
└── config.exs
├── doc
├── .build
├── 404.html
├── Vector.html
├── api-reference.html
├── index.html
└── search.html
├── lib
└── vector.ex
├── mix.exs
├── mix.lock
├── test
├── test_helper.exs
├── vector_identities_test.exs
└── vector_test.exs
└── validate.sh
/.formatter.exs:
--------------------------------------------------------------------------------
1 | # Used by "mix format"
2 | [
3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
4 | ]
5 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yaml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | format:
7 | name: Validation of source code
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v2.3.1
11 |
12 | - name: Install OTP and Elixir
13 | uses: erlef/setup-beam@v1
14 | with:
15 | otp-version: 25.2
16 | elixir-version: 1.14.2
17 |
18 | - name: Install dependencies
19 | run: mix deps.get
20 |
21 | - name: Run validations
22 | run: mix validate
23 |
24 | test:
25 | name: Test (Elixir ${{matrix.elixir}} | Erlang/OTP ${{matrix.otp}})
26 | runs-on: ubuntu-latest
27 | strategy:
28 | fail-fast: false
29 | matrix:
30 | include:
31 | - elixir: 1.14.x
32 | otp: 25
33 | - elixir: 1.14.x
34 | otp: 24
35 | - elixir: 1.13.x
36 | otp: 25
37 | - elixir: 1.13.x
38 | otp: 24
39 | - elixir: 1.12.x
40 | otp: 24
41 | env:
42 | MIX_ENV: test
43 |
44 |
45 | steps:
46 | - uses: actions/checkout@v1
47 |
48 | - name: Install OTP and Elixir
49 | uses: erlef/setup-beam@v1
50 | with:
51 | otp-version: ${{matrix.otp}}
52 | elixir-version: ${{matrix.elixir}}
53 |
54 | - name: Install dependencies
55 | run: mix deps.get --only test
56 |
57 | - name: Run tests
58 | run: mix test --trace
59 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # The directory Mix will write compiled artifacts to.
2 | /_build
3 |
4 | # If you run "mix test --cover", coverage assets end up here.
5 | /cover
6 |
7 | # The directory Mix downloads your dependencies sources to.
8 | /deps
9 |
10 | # Where 3rd-party dependencies like ExDoc output generated docs.
11 | /doc
12 |
13 | # If the VM crashes, it generates a dump, let's ignore it too.
14 | erl_crash.dump
15 |
16 | # Also ignore archive artifacts (built via "mix archive.build").
17 | *.ez
18 |
19 | .elixir_ls
20 |
21 | .DS_Store
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## [1.1.0] - 2023-01-09
4 |
5 | ### Changed
6 |
7 | - Updated CI to use GitHub Actions instead of travis-ci
8 | - Updated dependencies
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Powell Kinney
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Vector Math Library for Elixir
2 |
3 | 
4 | [](https://hex.pm/packages/vector)
5 | [](https://hexdocs.pm/vector)
6 |
7 | Library of common vector functions for use in geometric or graphical calculations.
8 |
9 | ## Installation
10 |
11 | ```elixir
12 | defp deps do
13 | [{:vector, "~> 1.1"}]
14 | end
15 | ```
16 |
17 | ## Usage
18 |
19 | **[Full Documentation](https://hexdocs.pm/vector/Vector.html)**
20 |
21 | The `Vector` module contains several functions that take one or more vectors.
22 | Each vector can be a 2- or 3-element tuple. It is possible to mix two- and
23 | three-dimensional vectors, in which case the `z` of the two-dimensional vector
24 | will be assumed 0.
25 |
26 | ```elixir
27 | Vector.dot({2, 3}, {1, 4}) #=> 14
28 | Vector.cross({2, 0, -1}, {0, 3, 3}) #=> {3, -6, 6}
29 | Vector.norm({3, -6, 6}) #=> 9
30 | Vector.unit({2, -1}) #=> {0.894, -0.447}
31 | Vector.add({2, 0, -1}, {0, 3, 3}) #=> {2, 3, 1}
32 | Vector.subtract({2, 0, -1}, {1, 3}) #=> {1, -3, 1}
33 | Vector.component({2, 3, -2}, :y) #=> 3
34 | ```
35 |
36 | ## Tests
37 |
38 | ```bash
39 | > mix test
40 | ```
41 |
42 | Included in the project are a suite of
43 | [algebraic identities](https://en.wikipedia.org/wiki/Vector_algebra_relations#Addition_and_multiplication_of_vectors)
44 | that can be run against a large generated set of vectors.
45 |
--------------------------------------------------------------------------------
/bench/snapshots/2016-03-30_11-52-51.snapshot:
--------------------------------------------------------------------------------
1 | duration:1.0;mem stats:false;sys mem stats:false
2 | module;test;tags;iterations;elapsed
3 | VectorBench zero-vector cross 3D 10000000 1066433
4 | VectorBench zero-vector cross 2D 100000000 6624801
5 | VectorBench unit vector 500 2564368
6 | VectorBench B (A . C) - C (A . B) 5 1639784
7 | VectorBench A x B 1000 1347786
8 | VectorBench A x (B x C) 10 1612823
9 | VectorBench A . B 2000 1774450
10 | VectorBench A . (B x C) 5 1500177
11 |
--------------------------------------------------------------------------------
/bench/snapshots/2019-02-27_18-33-20.snapshot:
--------------------------------------------------------------------------------
1 | duration:1.0;mem stats:false;sys mem stats:false
2 | module;test;tags;iterations;elapsed
3 | VectorBench A . (B x C) 10 1113209
4 | VectorBench A . B 5000 2131973
5 | VectorBench A x (B x C) 20 1609173
6 | VectorBench A x B 5000 3273046
7 | VectorBench B (A . C) - C (A . B) 10 1508749
8 | VectorBench unit vector 1000 2031061
9 | VectorBench zero-vector cross 2D 100000000 2992802
10 | VectorBench zero-vector cross 3D 100000000 6862010
11 |
--------------------------------------------------------------------------------
/bench/vector_bench.exs:
--------------------------------------------------------------------------------
1 | defmodule VectorBench do
2 | use Benchfella
3 | import Vector
4 |
5 | @values [-1, 0, 1, 2]
6 | @vectors (for x <- @values, y <- @values, do: {x, y}) ++ (for x <- @values, y <- @values, z <- @values, do: {x, y, z})
7 | @zero_2 {0, 0}
8 | @zero_3 {0, 0, 0}
9 |
10 | def run_vector_set_2(func) do
11 | for a <- @vectors, b <- @vectors, do: func.(a, b)
12 | end
13 |
14 | def run_vector_set_3(func) do
15 | for a <- @vectors, b <- @vectors, c <- @vectors, do: func.(a, b, c)
16 | end
17 |
18 | bench "zero-vector cross 2D" do
19 | Vector.cross(@zero_2, @zero_2)
20 | end
21 |
22 | bench "zero-vector cross 3D" do
23 | Vector.cross(@zero_3, @zero_3)
24 | end
25 |
26 | bench "unit vector" do
27 | run_vector_set_2 fn a, b-> cross(unit_safe(a), unit_safe(b)) end
28 | end
29 |
30 | bench "A x B" do
31 | run_vector_set_2 fn a, b -> cross(a, b) end
32 | end
33 |
34 | bench "A . B" do
35 | run_vector_set_2 fn a, b -> dot(a, b) end
36 | end
37 |
38 | bench "A . (B x C)" do
39 | run_vector_set_3 fn a, b, c -> cross(a, cross(b, c)) end
40 | end
41 |
42 | bench "A x (B x C)" do
43 | run_vector_set_3 fn a, b, c -> dot(a, cross(b, c)) end
44 | end
45 |
46 | bench "B (A . C) - C (A . B)" do
47 | run_vector_set_3 fn a, b, c -> subtract(multiply(b, dot(a, c)), multiply(c, dot(a, b))) end
48 | end
49 | end
50 |
--------------------------------------------------------------------------------
/config/config.exs:
--------------------------------------------------------------------------------
1 | # This file is responsible for configuring your application
2 | # and its dependencies with the aid of the Mix.Config module.
3 | import Config
4 |
5 | # This configuration is loaded before any dependency and is restricted
6 | # to this project. If another project depends on this project, this
7 | # file won't be loaded nor affect the parent project. For this reason,
8 | # if you want to provide default values for your application for
9 | # 3rd-party users, it should be done in your "mix.exs" file.
10 |
11 | # You can configure for your application as:
12 | #
13 | # config :vector, key: :value
14 | #
15 | # And access this configuration in your application as:
16 | #
17 | # Application.get_env(:vector, :key)
18 | #
19 | # Or configure a 3rd-party app:
20 | #
21 | # config :logger, level: :info
22 | #
23 |
24 | # It is also possible to import configuration files, relative to this
25 | # directory. For example, you can emulate configuration per environment
26 | # by uncommenting the line below and defining dev.exs, test.exs and such.
27 | # Configuration from the imported file will override the ones defined
28 | # here (which is why it is important to import them last).
29 | #
30 | # import_config "#{Mix.env}.exs"
31 |
--------------------------------------------------------------------------------
/doc/.build:
--------------------------------------------------------------------------------
1 | dist/html-399e30b9b028e3059575.css
2 | dist/html-399e30b9b028e3059575.js
3 | dist/html/fonts/icomoon.eot
4 | dist/html/fonts/icomoon.svg
5 | dist/html/fonts/icomoon.ttf
6 | dist/html/fonts/icomoon.woff
7 | dist/sidebar_items-71d22232a3.js
8 | api-reference.html
9 | search.html
10 | 404.html
11 | Vector.html
12 | index.html
13 |
--------------------------------------------------------------------------------
/doc/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Sorry, but the page you were trying to get to, does not exist. You
64 | may want to try searching this site using the sidebar
65 | or using our API Reference page
66 | to find what you were looking for.
Returns the unit vector parallel ot the given vector.
215 | This will raise an ArithmeticError if a zero-magnitude vector is given.
216 | Use unit_safe if there is a chance that a zero-magnitude vector
217 | will be sent
Returns the unit vector parallel ot the given vector.
676 | This will raise an ArithmeticError if a zero-magnitude vector is given.
677 | Use unit_safe if there is a chance that a zero-magnitude vector
678 | will be sent.