// Copyright 2014 The go-gl/mathgl Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // <<.Comment>> // Edit <<.TemplateName>> and run "go generate" to make changes. package mgl32 import ( "golang.org/x/image/math/f32" "math" ) type Vec2 f32.Vec2 type Vec3 f32.Vec3 type Vec4 f32.Vec4 func (v Vec2) Vec3(z float32) Vec3 { return Vec3{v[0], v[1], z} } func (v Vec2) Vec4(z, w float32) Vec4 { return Vec4{v[0], v[1], z, w} } func (v Vec3) Vec2() Vec2 { return Vec2{v[0], v[1]} } func (v Vec3) Vec4(w float32) Vec4 { return Vec4{v[0], v[1], v[2], w} } func (v Vec4) Vec2() Vec2 { return Vec2{v[0], v[1]} } func (v Vec4) Vec3() Vec3 { return Vec3{v[0], v[1], v[2]} } // Elem extracts the elements of the vector for direct value assignment. func (v Vec2) Elem() (x, y float32) { return v[0], v[1] } // Elem extracts the elements of the vector for direct value assignment. func (v Vec3) Elem() (x, y, z float32) { return v[0], v[1], v[2] } // Elem extracts the elements of the vector for direct value assignment. func (v Vec4) Elem() (x, y, z, w float32) { return v[0], v[1], v[2], v[3] } // The vector cross product is an operation only defined on 3D vectors. It is equivalent to // Vec3{v1[1]*v2[2]-v1[2]*v2[1], v1[2]*v2[0]-v1[0]*v2[2], v1[0]*v2[1] - v1[1]*v2[0]}. // Another interpretation is that it's the vector whose magnitude is |v1||v2|sin(theta) // where theta is the angle between v1 and v2. // // The cross product is most often used for finding surface normals. The cross product of vectors // will generate a vector that is perpendicular to the plane they form. // // Technically, a generalized cross product exists as an "(N-1)ary" operation // (that is, the 4D cross product requires 3 4D vectors). But the binary // 3D (and 7D) cross product is the most important. It can be considered // the area of a parallelogram with sides v1 and v2. // // Like the dot product, the cross product is roughly a measure of directionality. // Two normalized perpendicular vectors will return a vector with a magnitude of // 1.0 or -1.0 and two parallel vectors will return a vector with magnitude 0.0. // The cross product is "anticommutative" meaning v1.Cross(v2) = -v2.Cross(v1), // this property can be useful to know when finding normals, // as taking the wrong cross product can lead to the opposite normal of the one you want. func (v1 Vec3) Cross(v2 Vec3) Vec3 { return Vec3{v1[1]*v2[2] - v1[2]*v2[1], v1[2]*v2[0] - v1[0]*v2[2], v1[0]*v2[1] - v1[1]*v2[0]} } <> <> <<$type := typename $m 1>> // Add performs element-wise addition between two vectors. It is equivalent to iterating // over every element of v1 and adding the corresponding element of v2 to it. func (v1 <<$type>>) Add(v2 <<$type>>) <<$type>> { return <<$type>>{<> v1[<<$i>>] + v2[<<$i>>], <>} } // Sub performs element-wise subtraction between two vectors. It is equivalent to iterating // over every element of v1 and subtracting the corresponding element of v2 from it. func (v1 <<$type>>) Sub(v2 <<$type>>) <<$type>> { return <<$type>>{<> v1[<<$i>>] - v2[<<$i>>], <>} } // Mul performs a scalar multiplication between the vector and some constant value // c. This is equivalent to iterating over every vector element and multiplying by c. func (v1 <<$type>>) Mul(c float32) <<$type>> { return <<$type>>{<> v1[<<$i>>] * c, <>} } // Dot returns the dot product of this vector with another. There are multiple ways // to describe this value. One is the multiplication of their lengths and cos(theta) where // theta is the angle between the vectors: v1.v2 = |v1||v2|cos(theta). // // The other (and what is actually done) is the sum of the element-wise multiplication of all // elements. So for instance, two Vec3s would yield v1.x * v2.x + v1.y * v2.y + v1.z * v2.z. // // This means that the dot product of a vector and itself is the square of its Len (within // the bounds of floating points error). // // The dot product is roughly a measure of how closely two vectors are to pointing in the same // direction. If both vectors are normalized, the value will be -1 for opposite pointing, // one for same pointing, and 0 for perpendicular vectors. func (v1 <<$type>>) Dot(v2 <<$type>>) float32 { return <><> v1[<<$i>>]*v2[<<$i>>] <> } // Len returns the vector's length. Note that this is NOT the dimension of // the vector (len(v)), but the mathematical length. This is equivalent to the square // root of the sum of the squares of all elements. E.G. for a Vec2 it's // math.Hypot(v[0], v[1]). func (v1 <<$type>>) Len() float32 { <> return float32(math.Hypot(float64(v1[0]), float64(v1[1]))) <> return float32(math.Sqrt(float64(<>))) <> } // Normalize normalizes the vector. Normalization is (1/|v|)*v, // making this equivalent to v.Scale(1/v.Len()). If the len is 0.0, // this function will return an infinite value for all elements due // to how floating point division works in Go (n/0.0 = math.Inf(Sign(n))). // // Normalization makes a vector's Len become 1.0 (within the margin of floating point error), // while maintaining its directionality. // // (Can be seen here: http://play.golang.org/p/Aaj7SnbqIp ) func (v1 <<$type>>) Normalize() <<$type>> { l := 1.0 / v1.Len() return <<$type>>{<>v1[<<$i>>] * l,<>} } // ApproxEqual takes in a vector and does an element-wise // approximate float comparison as if FloatEqual had been used func (v1 <<$type>>) ApproxEqual(v2 <<$type>>) bool { for i := range v1 { if !FloatEqual(v1[i], v2[i]) { return false } } return true } // ApproxThresholdEq takes in a threshold for comparing two floats, and uses it to do an // element-wise comparison of the vector to another. func (v1 <<$type>>) ApproxEqualThreshold(v2 <<$type>>, threshold float32) bool { for i := range v1 { if !FloatEqualThreshold(v1[i], v2[i], threshold) { return false } } return true } // ApproxFuncEq takes in a func that compares two floats, and uses it to do an element-wise // comparison of the vector to another. This is intended to be used with FloatEqualFunc func (v1 <<$type>>) ApproxFuncEqual(v2 <<$type>>, eq func(float32, float32) bool) bool { for i := range v1 { if !eq(v1[i], v2[i]) { return false } } return true } <> // This is an element access func, it is equivalent to v[n] where // n is some valid index. The mappings are XYZW (X=0, Y=1 etc). Benchmarks // show that this is more or less as fast as direct acces, probably due to // inlining, so use v[0] or v.X() depending on personal preference. func (v <<$type>>) <>() float32 { return v[<<$i>>] } <> <> // Does the vector outer product // of two vectors. The outer product produces an // <<$m>>x<<$n>> matrix. E.G. a Vec<<$m>> * Vec<<$n>> = <>. // // The outer product can be thought of as the "opposite" // of the Dot product. The Dot product treats both vectors like matrices // oriented such that the left one has N columns and the right has N rows. // So Vec3.Vec3 = Mat1x3*Mat3x1 = Mat1 = Scalar. // // The outer product orients it so they're facing "outward": Vec2*Vec3 // = Mat2x1*Mat1x3 = Mat2x3. func (v1 <<$type>>) OuterProd<<$n>>(v2 <>) <> { return <>{<>v1[<<$i.M>>] * v2[<<$i.N>>], <>} } <> <> <>