From 8a8b5232a101857520de881beb83b5a5b6b57490 Mon Sep 17 00:00:00 2001 From: Kian-Meng Ang Date: Mon, 17 May 2021 20:57:03 +0800 Subject: [PATCH 1/2] Misc doc changes Besides other documentation changes, this commit ensures the generated HTML doc for HexDocs.pm will become the main reference doc for this Elixir library which leverage on latest features of ExDoc. --- .formatter.exs | 4 + .gitignore | 22 +- LICENSE => LICENSE.md | 0 README.md | 58 +++- doc/.build | 12 - doc/404.html | 86 ----- doc/Vector.html | 743 ----------------------------------------- doc/api-reference.html | 104 ------ doc/index.html | 11 - doc/search.html | 81 ----- lib/vector.ex | 87 ++++- mix.exs | 63 ++-- mix.lock | 40 +-- 13 files changed, 197 insertions(+), 1114 deletions(-) create mode 100644 .formatter.exs rename LICENSE => LICENSE.md (100%) delete mode 100644 doc/.build delete mode 100644 doc/404.html delete mode 100644 doc/Vector.html delete mode 100644 doc/api-reference.html delete mode 100644 doc/index.html delete mode 100644 doc/search.html diff --git a/.formatter.exs b/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/.gitignore b/.gitignore index ba47db6..e4fc965 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,17 @@ # The directory Mix will write compiled artifacts to. -/_build +/_build/ # If you run "mix test --cover", coverage assets end up here. -/cover +/cover/ # The directory Mix downloads your dependencies sources to. -/deps +/deps/ -# Where 3rd-party dependencies like ExDoc output generated docs. -/doc +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch # If the VM crashes, it generates a dump, let's ignore it too. erl_crash.dump @@ -16,6 +19,11 @@ erl_crash.dump # Also ignore archive artifacts (built via "mix archive.build"). *.ez -.elixir_ls +# Ignore package tarball (built via "mix hex.build"). +vector-*.tar + +# Temporary files for e.g. tests. +/tmp/ -.DS_Store \ No newline at end of file +# Misc. +/bench/ diff --git a/LICENSE b/LICENSE.md similarity index 100% rename from LICENSE rename to LICENSE.md diff --git a/README.md b/README.md index bf768ad..62f4a73 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,30 @@ # Vector Math Library for Elixir [![Build Status](https://travis-ci.org/pkinney/vector_ex.svg?branch=master)](https://travis-ci.org/pkinney/vector_ex) -[![Hex.pm](https://img.shields.io/hexpm/v/vector.svg)](https://hex.pm/packages/vector) +[![Module Version](https://img.shields.io/hexpm/v/vector.svg)](https://hex.pm/packages/vector) +[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/vector/) +[![Total Download](https://img.shields.io/hexpm/dt/vector.svg)](https://hex.pm/packages/vector) +[![License](https://img.shields.io/hexpm/l/vector.svg)](https://github.com/pkinney/vector/blob/master/LICENSE) +[![Last Updated](https://img.shields.io/github/last-commit/pkinney/vector_ex.svg)](https://github.com/pkinney/vector_ex/commits/master) + Library of common vector functions for use in geometric or graphical calculations. ## Installation +The package can be installed by adding `:vector` to your list of dependencies +in `mix.exs`: + ```elixir defp deps do - [{:vector, "~> 1.0"}] + [ + {:vector, "~> 1.0"} + ] end ``` ## Usage -**[Full Documentation](https://hexdocs.pm/vector/Vector.html)** - The `Vector` module contains several functions that take one or more vectors. Each vector can be a 2- or 3-element tuple. It is possible to mix two- and three-dimensional vectors, in which case the `z` of the two-dimensional vector @@ -32,12 +40,44 @@ Vector.subtract({2, 0, -1}, {1, 3}) #=> {1, -3, 1} Vector.component({2, 3, -2}, :y) #=> 3 ``` -## Tests +Included in the project are a suite of +[algebraic identities](https://en.wikipedia.org/wiki/Vector_algebra_relations#Addition_and_multiplication_of_vectors) that can be run against a large generated set of vectors. + +## Benchmark ```bash -> mix test +$ mix bench + +Settings: + duration: 1.0 s + +## VectorBench +[03:00:07] 1/8: A . (B x C) +[03:00:09] 2/8: A . B +[03:00:10] 3/8: A x (B x C) +[03:00:12] 4/8: A x B +[03:00:14] 5/8: B (A . C) - C (A . B) +[03:00:16] 6/8: unit vector +[03:00:20] 7/8: zero-vector cross 2D +[03:00:31] 8/8: zero-vector cross 3D + +Finished in 25.05 seconds + +## VectorBench +benchmark name iterations average time +zero-vector cross 2D 100000000 0.10 µs/op +zero-vector cross 3D 10000000 0.13 µs/op +A . B 1000 1091.15 µs/op +A x B 1000 1476.54 µs/op +unit vector 500 7180.52 µs/op +A x (B x C) 10 164521.80 µs/op +A . (B x C) 5 272087.20 µs/op +B (A . C) - C (A . B) 2 619590.00 µs/op ``` -Included in the project are a suite of -[algebraic identities](https://en.wikipedia.org/wiki/Vector_algebra_relations#Addition_and_multiplication_of_vectors) -that can be run against a large generated set of vectors. +## Copyright and License + +Copyright (c) 2017 Powell Kinney + +This library is released under the MIT License. See the [LICENSE.md](./LICENSE.md) file +for further details. diff --git a/doc/.build b/doc/.build deleted file mode 100644 index 0a55033..0000000 --- a/doc/.build +++ /dev/null @@ -1,12 +0,0 @@ -dist/html-399e30b9b028e3059575.css -dist/html-399e30b9b028e3059575.js -dist/html/fonts/icomoon.eot -dist/html/fonts/icomoon.svg -dist/html/fonts/icomoon.ttf -dist/html/fonts/icomoon.woff -dist/sidebar_items-71d22232a3.js -api-reference.html -search.html -404.html -Vector.html -index.html diff --git a/doc/404.html b/doc/404.html deleted file mode 100644 index 26f8b56..0000000 --- a/doc/404.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - 404 — vector v1.0.1 - - - - - - - - -
- - - - -
-
-
- - -

Page not found

- -

Sorry, but the page you were trying to get to, does not exist. You -may want to try searching this site using the sidebar - or using our API Reference page -to find what you were looking for.

- - -
-
-
-
- - - diff --git a/doc/Vector.html b/doc/Vector.html deleted file mode 100644 index 6883e0b..0000000 --- a/doc/Vector.html +++ /dev/null @@ -1,743 +0,0 @@ - - - - - - - - Vector — vector v1.0.1 - - - - - - - - -
- - - - -
-
-
- - -

- vector v1.0.1 -Vector

- - -
-

A library of two- and three-dimensional vector operations. All vectors -are represented as tuples with either two or three elements.

-

- - Examples -

- -
iex> # Vector Tripple Product Identity
-...> a = {2, 3, 1}
-...> b = {1, 4, -2}
-...> c = {-1, 2, 1}
-...> Vector.equal?(
-...>   Vector.cross(Vector.cross(a, b), c),
-...>   Vector.subtract(Vector.multiply(b, Vector.dot(a, c)), Vector.multiply(a, Vector.dot(b, c))))
-true
-
- -
-

- - - Link to this section - - Summary -

-
-

- Types -

-
- -
-
-
- vector() -
-
-
-
-

- Functions -

-
- -

Adds two vectors

-
-
-
- -

Returns the basis vector for the given axis

-
-
-
- -

Returns the scalar component for the axis given

-
-
-
- -

Returns the cross product of two vectors AB

-
-
-
- -

Returns the norm (magnitude) of the cross product of two vectors AB

-
-
-
- -

Divide a vector by scalar value s

-
-
-
- -

Returns the dot product of two vectors AB

-
-
-
- -

Compares two vectors for euqality, with an optional tolerance

-
-
-
- -

Multiply a vector by scalar value s

-
-
-
-
- norm(arg) -
-

Returns the norm (magnitude) of a vector

-
-
-
- -

Returns the square of the norm norm (magnitude) of a vector

-
-
-
- -

Returns a new coordinate by projecting a given length distance from -coordinate start along vector

-
-
-
- -

Reverses a vector

-
-
-
- -

Subtract vector B from vector A. Equivalent to Vector.add(A, Vector.revers(B))

-
-
-
-
- unit(v) -
-

Returns the unit vector parallel ot the given vector. -This will raise an ArithmeticError if a zero-magnitude vector is given. -Use unit_safe if there is a chance that a zero-magnitude vector -will be sent

-
-
-
- -

Returns the unit vector parallel ot the given vector, but will handle -the vectors {0, 0} and {0, 0, 0} by returning the same vector

-
-
-
-
- -
-

- - - Link to this section - -Types

-
-
-
- - - Link to this type - -

location() - -
-
location() :: {number(), number()} | {number(), number(), number()}
-
-

-
-
-
-
-
- - - Link to this type - -

vector() - -
-
vector() :: {number(), number()} | {number(), number(), number()}
-
-

-
-
-
-
-
-
-

- - - Link to this section - -Functions

-
-
-
- - - Link to this function - -

add(arg1, arg2) - -
-
add(vector(), vector()) :: vector()
-
-

-
-

Adds two vectors

-

- - Examples -

- -
iex> Vector.add({3, -4}, {2, 1})
-{5,-3}
-iex> Vector.add({-2, 0, 5}, {0, 0, 0})
-{-2, 0, 5}
-iex> Vector.add({2, 1, -2}, Vector.reverse({2, 1, -2}))
-{0, 0, 0}
-
-
-
-
- - - Link to this function - -

basis(atom) - -
-
basis(atom()) :: vector()
-
-

-
-

Returns the basis vector for the given axis

-

- - Examples -

- -
iex> Vector.basis(:x)
-{1, 0, 0}
-iex> Vector.basis(:y)
-{0, 1, 0}
-iex> Vector.component(Vector.basis(:y), :y)
-1
-
-
-
-
- - - Link to this function - -

component(arg, atom) - -
-
component(vector(), atom()) :: number()
-
-

-
-

Returns the scalar component for the axis given

-

- - Examples -

- -
iex> Vector.component({3, -4}, :y)
--4
-iex> Vector.component({-6, 0, 8}, :z)
-8
-iex> Vector.component({1, -2}, :z)
-0
-iex> Vector.component(Vector.basis(:x), :z)
-0
-
-
-
-
- - - Link to this function - -

cross(arg1, arg2) - -
-
cross(vector(), vector()) :: vector()
-
-

-
-

Returns the cross product of two vectors AB

-

- - Examples -

- -
iex> Vector.cross({2, 3}, {1, 4})
-{0, 0, 5}
-iex> Vector.cross({2, 2, -1}, {1, 4, 2})
-{8, -5, 6}
-iex> Vector.cross({3, -3, 1}, {4, 9, 2})
-{-15, -2, 39}
-
-
-
-
- - - Link to this function - -

cross_norm(arg1, arg2) - -
-
cross_norm(vector(), vector()) :: number()
-
-

-
-

Returns the norm (magnitude) of the cross product of two vectors AB

-

- - Examples -

- -
iex> Vector.cross_norm({2, 3}, {1, 4})
-5
-iex> Vector.cross_norm({1, 4}, {2, 2})
-6
-iex> Vector.cross_norm({2, 0, -1}, {0, 3, 3})
-9.0
-iex> Float.floor(:math.pow(Vector.cross_norm({2, 2, -1}, {1, 4, 2}), 2))
-125.0
-
-
-
-
- - - Link to this function - -

divide(arg, s) - -
-
divide(vector(), number()) :: vector()
-
-

-
-

Divide a vector by scalar value s

-

- - Examples -

- -
iex> Vector.divide({3, -4}, 2.5)
-{1.2, -1.6}
-iex> Vector.divide({-2, 0, 5}, -2)
-{1.0, 0.0, -2.5}
-
-
-
-
- - - Link to this function - -

dot(arg1, arg2) - -
-
dot(vector(), vector()) :: number()
-
-

-
-

Returns the dot product of two vectors AB

-

- - Examples -

- -
iex> Vector.dot({2, 3}, {1, 4})
-14
-iex> Vector.dot({1, 4}, {2, 2})
-10
-iex> Vector.dot({2, 0, -1}, {0, 3, 3})
--3
-
-
-
- - -
- - - Link to this function - -

equal?(a, b, tolerance \\ 0.0) - -
-
equal?(vector(), vector(), number()) :: boolean()
-
-

-
-

Compares two vectors for euqality, with an optional tolerance

-

- - Examples -

- -
iex> Vector.equal?({3, -4}, {3, -4})
-true
-iex> Vector.equal?({3, -4}, {3.0001, -3.9999})
-false
-iex> Vector.equal?({3, -4}, {3.0001, -3.9999}, 0.001)
-true
-iex> Vector.equal?({3, -4, 1}, {3.0001, -3.9999, 1.0}, 0.001)
-true
-
-
-
-
- - - Link to this function - -

multiply(arg, s) - -
-
multiply(vector(), number()) :: vector()
-
-

-
-

Multiply a vector by scalar value s

-

- - Examples -

- -
iex> Vector.multiply({3, -4}, 2.5)
-{7.5, -10.0}
-iex> Vector.multiply({-2, 0, 5}, -2)
-{4, 0, -10}
-
-
-
-
- - - Link to this function - -

norm(arg) - -
-
norm(vector()) :: number()
-
-

-
-

Returns the norm (magnitude) of a vector

-

- - Examples -

- -
iex> Vector.norm({3, 4})
-5.0
-iex> Vector.norm({-1, 0})
-1
-iex> Vector.norm({0, -2, 0})
-2
-
-
-
-
- - - Link to this function - -

norm_squared(arg) - -
-
norm_squared(vector()) :: number()
-
-

-
-

Returns the square of the norm norm (magnitude) of a vector

-

- - Examples -

- -
iex> Vector.norm_squared({3, 4})
-25
-iex> Vector.norm_squared({1, 0})
-1
-iex> Vector.norm_squared({2, 0, -1})
-5
-iex> Vector.norm_squared({-2, 3, 1})
-14
-
-
-
-
- - - Link to this function - -

project(vector, start, distance) - -
-
project(vector(), location(), number()) :: location()
-
-

-
-

Returns a new coordinate by projecting a given length distance from -coordinate start along vector

-

- - Examples -

- -
iex> Vector.project({3, -4}, {-1, 1}, 4)
-{1.4, -2.2}
-iex> Vector.project({-6, 0, 8}, {1, -2, 0.4}, 2.5)
-{-0.5, -2.0, 2.4}
-iex> Vector.project({-2, 1, 3}, {0, 0, 0}, 2.5) |> Vector.norm()
-2.5
-
-
-
-
- - - Link to this function - -

reverse(arg) - -
-
reverse(vector()) :: vector()
-
-

-
-

Reverses a vector

-

- - Examples -

- -
iex> Vector.reverse({3, -4})
-{-3, 4}
-iex> Vector.reverse({-2, 0, 5})
-{2, 0, -5}
-iex> Vector.cross_norm({-2, 3, 5}, Vector.reverse({-2, 3, 5}))
-0
-
-
-
-
- - - Link to this function - -

subtract(a, b) - -
-
subtract(vector(), vector()) :: vector()
-
-

-
-

Subtract vector B from vector A. Equivalent to Vector.add(A, Vector.revers(B))

-

- - Examples -

- -
iex> Vector.subtract({3, -4}, {2, 1})
-{1,-5}
-iex> Vector.subtract({-2, 0, 5}, {-3, 1, 2})
-{1, -1, 3}
-
-
-
-
- - - Link to this function - -

unit(v) - -
-
unit(vector()) :: vector()
-
-

-
-

Returns the unit vector parallel ot the given vector. -This will raise an ArithmeticError if a zero-magnitude vector is given. -Use unit_safe if there is a chance that a zero-magnitude vector -will be sent.

-

- - Examples -

- -
iex> Vector.unit({3, 4})
-{0.6, 0.8}
-iex> Vector.unit({8, 0, 6})
-{0.8, 0.0, 0.6}
-iex> Vector.unit({-2, 0, 0})
-{-1.0, 0.0, 0.0}
-iex> Vector.unit({0, 0, 0})
-** (ArithmeticError) bad argument in arithmetic expression
-
-
-
-
- - - Link to this function - -

unit_safe(v) - -
-
unit_safe(vector()) :: vector()
-
-

-
-

Returns the unit vector parallel ot the given vector, but will handle -the vectors {0, 0} and {0, 0, 0} by returning the same vector

-

- - Examples -

- -
iex> Vector.unit_safe({3, 4})
-{0.6, 0.8}
-iex> Vector.unit_safe({0, 0})
-{0, 0}
-iex> Vector.unit_safe({0, 0, 0})
-{0, 0, 0}
-
-
-
-
- -
-
-
-
- - - - diff --git a/doc/api-reference.html b/doc/api-reference.html deleted file mode 100644 index c6b7d8f..0000000 --- a/doc/api-reference.html +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - API Reference — vector v1.0.1 - - - - - - - - -
- - - - -
-
-
- - -

- vector v1.0.1 - API Reference -

- -
-

- - Modules -

- -
-
-
- Vector -
-

A library of two- and three-dimensional vector operations. All vectors -are represented as tuples with either two or three elements

-
-
-
-
- - - -
-
-
-
- - - - diff --git a/doc/index.html b/doc/index.html deleted file mode 100644 index 14644de..0000000 --- a/doc/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - vector v1.0.1 — Documentation - - - - - - diff --git a/doc/search.html b/doc/search.html deleted file mode 100644 index 19fba92..0000000 --- a/doc/search.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - Search — vector v1.0.1 - - - - - - - - -
- - - - -
-
-
- - - -
-
-
-
- - - diff --git a/lib/vector.ex b/lib/vector.ex index 59078fc..b04d250 100644 --- a/lib/vector.ex +++ b/lib/vector.ex @@ -5,6 +5,7 @@ defmodule Vector do are represented as tuples with either two or three elements. ## Examples + iex> # Vector Tripple Product Identity ...> a = {2, 3, 1} ...> b = {1, 4, -2} @@ -19,16 +20,19 @@ defmodule Vector do @type location :: {number, number} | {number, number, number} @doc ~S""" - Returns the cross product of two vectors *A*⨯*B* + Returns the cross product of two vectors *A*⨯*B*. ## Examples iex> Vector.cross({2, 3}, {1, 4}) {0, 0, 5} + iex> Vector.cross({2, 2, -1}, {1, 4, 2}) {8, -5, 6} + iex> Vector.cross({3, -3, 1}, {4, 9, 2}) {-15, -2, 39} + """ @spec cross(vector, vector) :: vector def cross({x1, y1}, {x2, y2}), do: {0, 0, x1 * y2 - y1 * x2} @@ -41,18 +45,22 @@ defmodule Vector do end @doc ~S""" - Returns the norm (magnitude) of the cross product of two vectors *A*⨯*B* + Returns the norm (magnitude) of the cross product of two vectors *A*⨯*B*. ## Examples iex> Vector.cross_norm({2, 3}, {1, 4}) 5 + iex> Vector.cross_norm({1, 4}, {2, 2}) 6 + iex> Vector.cross_norm({2, 0, -1}, {0, 3, 3}) 9.0 + iex> Float.floor(:math.pow(Vector.cross_norm({2, 2, -1}, {1, 4, 2}), 2)) 125.0 + """ @spec cross_norm(vector, vector) :: number def cross_norm({x1, y1}, {x2, y2}), do: cross_norm({x1, y1, 0}, {x2, y2, 0}) @@ -61,16 +69,19 @@ defmodule Vector do end @doc ~S""" - Returns the dot product of two vectors *A*⨯*B* + Returns the dot product of two vectors *A*⨯*B*. ## Examples iex> Vector.dot({2, 3}, {1, 4}) 14 + iex> Vector.dot({1, 4}, {2, 2}) 10 + iex> Vector.dot({2, 0, -1}, {0, 3, 3}) -3 + """ @spec dot(vector, vector) :: number def dot({x1, y1}, {x2, y2}), do: dot({x1, y1, 0}, {x2, y2, 0}) @@ -81,16 +92,19 @@ defmodule Vector do end @doc ~S""" - Returns the norm (magnitude) of a vector + Returns the norm (magnitude) of a vector. ## Examples iex> Vector.norm({3, 4}) 5.0 + iex> Vector.norm({-1, 0}) 1 + iex> Vector.norm({0, -2, 0}) 2 + """ @spec norm(vector) :: number def norm({x, y}), do: norm({x, y, 0}) @@ -100,18 +114,22 @@ defmodule Vector do def norm({x, y, z}), do: :math.sqrt(norm_squared({x, y, z})) @doc ~S""" - Returns the square of the norm norm (magnitude) of a vector + Returns the square of the norm norm (magnitude) of a vector. ## Examples iex> Vector.norm_squared({3, 4}) 25 + iex> Vector.norm_squared({1, 0}) 1 + iex> Vector.norm_squared({2, 0, -1}) 5 + iex> Vector.norm_squared({-2, 3, 1}) 14 + """ @spec norm_squared(vector) :: number def norm_squared({x, y}), do: norm_squared({x, y, 0}) @@ -120,8 +138,10 @@ defmodule Vector do end @doc ~S""" - Returns the unit vector parallel ot the given vector. + Returns the unit vector parallel to the given vector. + This will raise an `ArithmeticError` if a zero-magnitude vector is given. + Use `unit_safe` if there is a chance that a zero-magnitude vector will be sent. @@ -129,12 +149,16 @@ defmodule Vector do iex> Vector.unit({3, 4}) {0.6, 0.8} + iex> Vector.unit({8, 0, 6}) {0.8, 0.0, 0.6} + iex> Vector.unit({-2, 0, 0}) {-1.0, 0.0, 0.0} + iex> Vector.unit({0, 0, 0}) ** (ArithmeticError) bad argument in arithmetic expression + """ @spec unit(vector) :: vector def unit({x, 0, 0}), do: {x / abs(x), 0.0, 0.0} @@ -143,17 +167,20 @@ defmodule Vector do def unit(v), do: divide(v, norm(v)) @doc ~S""" - Returns the unit vector parallel ot the given vector, but will handle - the vectors `{0, 0}` and `{0, 0, 0}` by returning the same vector + Returns the unit vector parallel to the given vector, but will handle + the vectors `{0, 0}` and `{0, 0, 0}` by returning the same vector. ## Examples iex> Vector.unit_safe({3, 4}) {0.6, 0.8} + iex> Vector.unit_safe({0, 0}) {0, 0} + iex> Vector.unit_safe({0, 0, 0}) {0, 0, 0} + """ @spec unit_safe(vector) :: vector def unit_safe({0, 0}), do: {0, 0} @@ -161,32 +188,38 @@ defmodule Vector do def unit_safe(v), do: unit(v) @doc ~S""" - Reverses a vector + Reverses a vector. ## Examples iex> Vector.reverse({3, -4}) {-3, 4} + iex> Vector.reverse({-2, 0, 5}) {2, 0, -5} + iex> Vector.cross_norm({-2, 3, 5}, Vector.reverse({-2, 3, 5})) 0 + """ @spec reverse(vector) :: vector def reverse({x, y}), do: {-x, -y} def reverse({x, y, z}), do: {-x, -y, -z} @doc ~S""" - Adds two vectors + Adds two vectors. ## Examples iex> Vector.add({3, -4}, {2, 1}) {5,-3} + iex> Vector.add({-2, 0, 5}, {0, 0, 0}) {-2, 0, 5} + iex> Vector.add({2, 1, -2}, Vector.reverse({2, 1, -2})) {0, 0, 0} + """ @spec add(vector, vector) :: vector def add({x1, y1}, {x2, y2}), do: {x1 + x2, y1 + y2} @@ -195,41 +228,47 @@ defmodule Vector do def add({x1, y1, z1}, {x2, y2, z2}), do: {x1 + x2, y1 + y2, z1 + z2} @doc ~S""" - Subtract vector *B* from vector *A*. Equivalent to `Vector.add(A, Vector.revers(B))` + Subtract vector *B* from vector *A*. Equivalent to `Vector.add(A, Vector.revers(B))`. ## Examples iex> Vector.subtract({3, -4}, {2, 1}) {1,-5} + iex> Vector.subtract({-2, 0, 5}, {-3, 1, 2}) {1, -1, 3} + """ @spec subtract(vector, vector) :: vector def subtract(a, b), do: add(a, reverse(b)) @doc ~S""" - Multiply a vector by scalar value `s` + Multiply a vector by scalar value `s`. ## Examples iex> Vector.multiply({3, -4}, 2.5) {7.5, -10.0} + iex> Vector.multiply({-2, 0, 5}, -2) {4, 0, -10} + """ @spec multiply(vector, number) :: vector def multiply({x, y}, s), do: {x * s, y * s} def multiply({x, y, z}, s), do: {x * s, y * s, z * s} @doc ~S""" - Divide a vector by scalar value `s` + Divide a vector by scalar value `s`. ## Examples iex> Vector.divide({3, -4}, 2.5) {1.2, -1.6} + iex> Vector.divide({-2, 0, 5}, -2) {1.0, 0.0, -2.5} + """ @spec divide(vector, number) :: vector def divide({x, y}, s), do: {x / s, y / s} @@ -237,16 +276,19 @@ defmodule Vector do @doc ~S""" Returns a new coordinate by projecting a given length `distance` from - coordinate `start` along `vector` + coordinate `start` along `vector`. ## Examples iex> Vector.project({3, -4}, {-1, 1}, 4) {1.4, -2.2} + iex> Vector.project({-6, 0, 8}, {1, -2, 0.4}, 2.5) {-0.5, -2.0, 2.4} + iex> Vector.project({-2, 1, 3}, {0, 0, 0}, 2.5) |> Vector.norm() 2.5 + """ @spec project(vector, location, number) :: location def project(vector, start, distance) do @@ -257,18 +299,22 @@ defmodule Vector do end @doc ~S""" - Compares two vectors for equality, with an optional tolerance + Compares two vectors for equality, with an optional tolerance. ## Examples iex> Vector.equal?({3, -4}, {3, -4}) true + iex> Vector.equal?({3, -4}, {3.0001, -3.9999}) false + iex> Vector.equal?({3, -4}, {3.0001, -3.9999}, 0.001) true + iex> Vector.equal?({3, -4, 1}, {3.0001, -3.9999, 1.0}, 0.001) true + """ @spec equal?(vector, vector, number) :: boolean def equal?(a, b, tolerance \\ 0.0) do @@ -276,18 +322,22 @@ defmodule Vector do end @doc ~S""" - Returns the scalar component for the axis given + Returns the scalar component for the axis given. ## Examples iex> Vector.component({3, -4}, :y) -4 + iex> Vector.component({-6, 0, 8}, :z) 8 + iex> Vector.component({1, -2}, :z) 0 + iex> Vector.component(Vector.basis(:x), :z) 0 + """ @spec component(vector, atom) :: number def component({x, _}, :x), do: x @@ -298,16 +348,19 @@ defmodule Vector do def component({_, _, z}, :z), do: z @doc ~S""" - Returns the basis vector for the given axis + Returns the basis vector for the given axis. ## Examples iex> Vector.basis(:x) {1, 0, 0} + iex> Vector.basis(:y) {0, 1, 0} + iex> Vector.component(Vector.basis(:y), :y) 1 + """ @spec basis(atom) :: vector def basis(:x), do: {1, 0, 0} diff --git a/mix.exs b/mix.exs index 228376b..cda8649 100644 --- a/mix.exs +++ b/mix.exs @@ -1,31 +1,34 @@ defmodule Vector.Mixfile do use Mix.Project + @source_url "https://github.com/pkinney/vector_ex" + @version "1.0.1" + def project do - [app: :vector, - version: "1.0.1", - elixir: "~> 1.2", - description: description(), - package: package(), - build_embedded: Mix.env == :prod, - start_permanent: Mix.env == :prod, - test_coverage: [tool: ExCoveralls], - preferred_cli_env: [coveralls: :test], - dialyzer: [plt_add_apps: [:poison, :mix]], - deps: deps()] + [ + app: :vector, + version: @version, + elixir: "~> 1.2", + build_embedded: Mix.env() == :prod, + start_permanent: Mix.env() == :prod, + test_coverage: [tool: ExCoveralls], + preferred_cli_env: [coveralls: :test], + dialyzer: [plt_add_apps: [:poison, :mix]], + package: package(), + deps: deps(), + docs: docs() + ] end - # Configuration for the OTP application - # - # Type "mix help compile.app" for more information def application do - [applications: [:logger]] + [ + applications: [:logger] + ] end defp deps do [ - {:earmark, "~> 1.0", only: :dev}, - {:ex_doc, "~> 0.18", only: :dev}, + {:ex_doc, ">= 0.0.0", only: :dev, runtime: false}, {:benchfella, "~> 0.3", only: :dev}, {:excoveralls, "~> 0.4", only: :test}, {:dialyxir, "~> 0.4", only: [:dev], runtime: false}, @@ -33,19 +36,29 @@ defmodule Vector.Mixfile do ] end - defp description do - """ - Library of common vector functions for use in geometric or graphical calculations. - """ - end - defp package do [ + description: + "Library of common vector functions for use in geometric or graphical calculations.", files: ["lib", "mix.exs", "README*"], maintainers: ["Powell Kinney"], licenses: ["MIT"], - links: %{ "GitHub" => "https://github.com/pkinney/vector_ex", - "Docs" => "https://hexdocs.pm/vector/Vector.html"} + links: %{ + "GitHub" => @source_url, + } + ] + end + + defp docs do + [ + extras: [ + "LICENSE.md": [title: "License"], + "README.md": [title: "Overview"] + ], + main: "readme", + source_url: @source_url, + api_reference: false, + formatters: ["html"] ] end end diff --git a/mix.lock b/mix.lock index 8800ed7..f545360 100644 --- a/mix.lock +++ b/mix.lock @@ -1,21 +1,23 @@ %{ - "benchfella": {:hex, :benchfella, "0.3.5", "b2122c234117b3f91ed7b43b6e915e19e1ab216971154acd0a80ce0e9b8c05f5", [:mix], []}, - "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], []}, - "certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], []}, - "credo": {:hex, :credo, "0.8.6", "335f723772d35da499b5ebfdaf6b426bfb73590b6fcbc8908d476b75f8cbca3f", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, optional: false]}]}, - "dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], []}, - "earmark": {:hex, :earmark, "1.3.1", "73812f447f7a42358d3ba79283cfa3075a7580a3a2ed457616d6517ac3738cb9", [:mix], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.19.3", "3c7b0f02851f5fc13b040e8e925051452e41248f685e40250d7e40b07b9f8c10", [:mix], [{:earmark, "~> 1.2", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, - "excoveralls": {:hex, :excoveralls, "0.7.2", "f69ede8c122ccd3b60afc775348a53fc8c39fe4278aee2f538f0d81cc5e7ff3a", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, optional: false]}]}, - "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, optional: false]}]}, - "hackney": {:hex, :hackney, "1.9.0", "51c506afc0a365868469dcfc79a9d0b94d896ec741cfd5bd338f49a5ec515bfe", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, optional: false]}, {:idna, "5.1.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]}, - "idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, optional: false]}]}, - "jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], []}, - "makeup": {:hex, :makeup, "0.8.0", "9cf32aea71c7fe0a4b2e9246c2c4978f9070257e5c9ce6d4a28ec450a839b55f", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.13.0", "be7a477997dcac2e48a9d695ec730b2d22418292675c75aa2d34ba0909dcdeda", [:mix], [{:makeup, "~> 0.8", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []}, - "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []}, - "nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm"}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []}, - "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], []}, + "benchfella": {:hex, :benchfella, "0.3.5", "b2122c234117b3f91ed7b43b6e915e19e1ab216971154acd0a80ce0e9b8c05f5", [:mix], [], "hexpm", "23f27cbc482cbac03fc8926441eb60a5e111759c17642bac005c3225f5eb809d"}, + "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"}, + "certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], [], "hexpm", "fdc6066ceeccb3aa14049ab6edf0b9af3b64ae1b0db2a92d5c52146f373bbb1c"}, + "credo": {:hex, :credo, "0.8.6", "335f723772d35da499b5ebfdaf6b426bfb73590b6fcbc8908d476b75f8cbca3f", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm", "14dde2b851709115a578e43158c13ad97724eceb70320c51784952b88ee64814"}, + "dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm", "6c32a70ed5d452c6650916555b1f96c79af5fc4bf286997f8b15f213de786f73"}, + "earmark": {:hex, :earmark, "1.3.1", "73812f447f7a42358d3ba79283cfa3075a7580a3a2ed457616d6517ac3738cb9", [:mix], [], "hexpm", "000aaeff08919e95e7aea13e4af7b2b9734577b3e6a7c50ee31ee88cab6ec4fb"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.13", "0c98163e7d04a15feb62000e1a891489feb29f3d10cb57d4f845c405852bbef8", [:mix], [], "hexpm", "d602c26af3a0af43d2f2645613f65841657ad6efc9f0e361c3b6c06b578214ba"}, + "ex_doc": {:hex, :ex_doc, "0.24.2", "e4c26603830c1a2286dae45f4412a4d1980e1e89dc779fcd0181ed1d5a05c8d9", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "e134e1d9e821b8d9e4244687fb2ace58d479b67b282de5158333b0d57c6fb7da"}, + "excoveralls": {:hex, :excoveralls, "0.7.2", "f69ede8c122ccd3b60afc775348a53fc8c39fe4278aee2f538f0d81cc5e7ff3a", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "ef8fc1c6014b16a68dccfba3513aa41283d731eeaf8a1b704bbb072cb1ab89cb"}, + "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "32e95820a97cffea67830e91514a2ad53b888850442d6d395f53a1ac60c82e07"}, + "hackney": {:hex, :hackney, "1.9.0", "51c506afc0a365868469dcfc79a9d0b94d896ec741cfd5bd338f49a5ec515bfe", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "e38f4a7937b6dfc5fa87403ece26b1826bc81838f09ac57fabf2f7a9885fe818"}, + "idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fc1a2f7340c422650504b1662f28fdf381f34cbd30664e8491744e52c9511d40"}, + "jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], [], "hexpm", "b4c5d3230b397c8d95579e4a3d72826bb6463160130ccf4182f5be8579b5f44c"}, + "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, + "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm", "7a4c8e1115a2732a67d7624e28cf6c9f30c66711a9e92928e745c255887ba465"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm", "4f8805eb5c8a939cf2359367cb651a3180b27dfb48444846be2613d79355d65e"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm", "da1d9bef8a092cc7e1e51f1298037a5ddfb0f657fe862dfe7ba4c5807b551c29"}, } From e2b49496ffc5cd7e66e7120105ca2dcafd7284a1 Mon Sep 17 00:00:00 2001 From: "Kian-Meng, Ang" Date: Sun, 26 Dec 2021 18:30:55 +0800 Subject: [PATCH 2/2] Code review changes --- .gitignore | 4 +++- mix.exs | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e4fc965..fdaf4aa 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,6 @@ vector-*.tar /tmp/ # Misc. -/bench/ +.DS_Store +.elixir_ls/ +/bench/snapshots/ diff --git a/mix.exs b/mix.exs index cda8649..0d99dba 100644 --- a/mix.exs +++ b/mix.exs @@ -45,6 +45,7 @@ defmodule Vector.Mixfile do licenses: ["MIT"], links: %{ "GitHub" => @source_url, + "Docs" => "https://hexdocs.pm/vector/Vector.html" } ] end