xkonti / govec Goto Github PK
View Code? Open in Web Editor NEWGo library providing 2D and 3D vector operations
License: MIT License
Go library providing 2D and 3D vector operations
License: MIT License
Rotates a vector by an angle specified in degrees.
Functions for integer vectors should return a float vector.
Set up benchmarks to compare performance between situations where a small helper function is implemented and where calculations are manually inlined. For example, what is the difference in performance here:
// Helper function 1
func dot(x1 T, y1 T, x2 T, y2 T) T {
return x1*x2 + y1*y2
}
// Helper function 2
func magnitude(x, y) float64 {
return math.Sqrt(float64(x*x + y*y))
}
// Using helpers:
func (v V2F[T]) AngleBetweenRad(v2 V2F[T]) float64 {
dotProduct := dot(v.x, v.y, v2.x, v2.y)
magnitudeV := magnitude(v.x, v.y)
magnitudeV2 := magnitude(v2.x, v2.y)
cosTheta := float64(dotProduct) / (magnitudeV * magnitudeV2)
return math.Acos(math.Min(math.Max(cosTheta, -1.0), 1.0))
}
// Manually inlined code:
func (v V2F[T]) AngleBetweenRad(v2 V2F[T]) float64 {
dotProduct := v.X*v2.X + v.Y*v2.Y
magnitudeV := math.Sqrt(float64(v.X*v.X + v.Y*v.Y))
magnitudeV2 := math.Sqrt(float64(v2.X*v2.X + v2.Y*v2.Y))
cosTheta := float64(dotProduct) / (magnitudeV * magnitudeV2)
return math.Acos(math.Min(math.Max(cosTheta, -1.0), 1.0))
}
This is to decide if the library needs to maintain lots of copy-pasted inlined code or it's safe to extract some of that complexity into reusable functions without reducing performance.
Creates a normalized vector from an angle in radians.
Available only for float vectors.
Generates a vector with random components within a specified range. The range is specified by 2 vectors.
fromVec := V3F{12.3, 45.6, 78.9}
toX, toY, toZ := 12.0, 34.0, 15.0
toVec := V3F{toX, toY, toZ}
random1 := fromVec.RandBetween(toVec) // Returns a new random vector
random2 := fromVec.RandBetweenComp(toX, toY, toZ) // Returns a new random vector
rangeVec.RandBetweenInPlace(toVec) // Updates the existing vector with random values
rangeVec.RandBetweenInPlace(toX, toY, toZ) // Updates the existing vector with random values
This operation clamps vector's length between specified values. This will basically scale the vector up or down in case it's length is too great or too little. Integer vectors will be converted into a float64
variant.
vec1.ClampLen(min, max)
The Max
operation should return the maximum component values from two vectors.
The operation calculates sinus of each vector components. For integer vectors it returns a float64 vector.
vec1.Sin()
Please feel free to pick any of the not-implemented operation and add tests - even if not coplete.
All operations should be covered by tests to enforce that the library is correct at all times.
The challenge in thoroughly testing the library lays in the sheer amount of possible variants of each operation:
V2F
, V3F
, V2I
, V3I
)Comp
InPlace
CompInPlace
V2F
and V3F
allow for float32
and float64
turning it from 2 to 4 permutationsV2I
and V3I
allow for int
, int8
, int16
, int32
and int64
turning it from 2 to 10 permutationsAn operation like Add
could be considered to have a high number of variants:
Add
, AddComp
, AddInPlace
, AddCompInPlace
= 4 variantsV2F
and V3F
introduce 4 variants of each = 4*4 = 16variantsV2I
and V3I
introduce 10 more variants of each = 4*10 = 40variantsThat produces 16+40=56 variants of Add
to run multiple tests on!
Checkmark | Name of the function | Status |
---|---|---|
✖️ | Abs | Partial ( #37 ) |
✖️ | Add | Only basic for V2F and V2I implemented |
✖️ | AddScalar | NONE |
✖️ | AngleBetweenDeg | NONE |
✖️ | AngleBetweenRad | NONE |
✖️ | Apply | NONE |
✖️ | Array | NONE |
✖️ | Ceil | NONE |
✖️ | ClampComp | NONE |
✖️ | ClampLen | NONE |
✖️ | Cross | NONE |
✖️ | Discard | NONE |
✖️ | Distance | NONE |
✖️ | Div | NONE |
✖️ | DivScalar | NONE |
✖️ | Dot | NONE |
✖️ | Extend | NONE |
✖️ | Floor | NONE |
✖️ | Insert | NONE |
✖️ | Inv | NONE |
✖️ | IsZero | NONE |
✖️ | Len | NONE |
✖️ | LenSqrt | NONE |
✖️ | Math | NONE |
✔️ | Max | Implemented |
✔️ | Min | Implemented |
✖️ | Mod | NONE |
✖️ | ModScalar | NONE |
✖️ | Mul | NONE |
✖️ | MulScalar | NONE |
✖️ | Neg | NONE |
✖️ | New | NONE |
✖️ | Norm | NONE |
✖️ | Pow | NONE |
✖️ | Pow2 | NONE |
✖️ | Pow3 | NONE |
✖️ | PowN | NONE |
✖️ | PowNFloat | NONE |
✖️ | Round | NONE |
✖️ | Slice | NONE |
✖️ | Split | NONE |
✖️ | Sqrt | NONE |
✖️ | Sub | NONE |
✖️ | SubScalar | NONE |
✖️ | Swizzle | NONE |
The Min
operation should return the minimum component values from two vectors.
Calculates the angle between two vectors in degrees.
This operation would calculate modulus for each component by a given scalar:
vec2 = vec1.ModScalar(13)
Calculates the distance between two vectors.
float
)Functions:
(v V2F[T]) Distance(v2 V2F[T]) float64
(v V2F[T]) DistanceComp(x T, y T) float64
(v V3F[T]) Distance(v2 V3F[T]) float64
(v V3F[T]) DistanceComp(x T, y T, z T) float64
(v V2I[T]) Distance(v2 V2I[T]) float64
(v V2I[T]) DistanceComp(x T, y T) float64
(v V3I[T]) Distance(v2 V3I[T]) float64
(v V3I[T]) DistanceComp(x T, y T, z T) float64
Rotates a vector by an angle specified in radians.
Functions for integer vectors should return a float vector.
The conversion from radians to degrees is widespread throughout the library. It would be useful to optimize it by precalculating the conversion factor (180 / Pi).
Tests should be ran on every Pull Request. This will allow for:
Tests should be ran only for Pull Requests and not for merges to main
branch as PRs are the only way to commit to main
.
This could be a starting point for .github/workflows/pr-check.yml
file:
name: Test PR
on:
pull_request:
branches:
- main
jobs:
check-pr:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Go
uses: ???
- name: Run tests
uses: ???
Checks if the vector is a zero vector.
Example of usage:
vec1 := V2F[float64]{X: 12, Y: 0}
result := vec1.IsZero()
// result is false
The operation calculates the average of all vector components. For integer vectors it returns a float64 value.
vec1.Average()
Linearly interpolates between two vectors.
Functions for integer vectors should return a float vector.
Operations on float64
are more expensive than on float32
. The library should be refactored so that float64
is as limited as possible. Things to consider:
float64
to float32
to perform further operations. It might be cheaper to continue with float64
in between areas where float64
is required.float64
the conversion cost might be considered free as it would need to happen at some point anyway.The operation calculates tangent of each vector components. For integer vectors it returns a float64 vector.
vec1.Tan()
Generates a vector with random components within a specified range. The range is specified by vector/component and a zero vector.
// These are the same
V2F{12, 13}.RandIn() == V2F{12, 13}.RandBetween(V2F{0, 0})
rangeX, rangeY, rangeZ := 12, 34, 15
rangeVec := V3I{rangeX, rangeY, rangeZ}
random1 := rangeVec.RandIn() // Returns a new random vector
rangeVec.RandInInPlace() // Updates the existing vector with random values
Creates a normalized vector from an angle in degrees.
Available only for float vectors.
The operation calculates cosine of each vector components. For integer vectors it returns a float64 vector.
vec1.Cos()
Generates a normal vector with random components. Available only for float types. Make sure vector is normalized.
vec1 := govec.RandV2F[float64]()
vec2 := govec.RandV2F[float32]()
vec3 := govec.RandV3F[float64]()
vec4 := govec.RandV3F[float32]()
This operation clamps each component between corresponding components of two provided vectors.
vec1.ClampComp(vec2, vec3)
Calculates the angle between two vectors in radians.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.