github.com/liucxer/courier@v1.7.1/h3/vec2d.go (about) 1 package h3 2 3 import ( 4 "fmt" 5 "math" 6 ) 7 8 /** 9 * @brief 2D floating-point vector 10 */ 11 type Vec2d struct { 12 x float64 13 y float64 14 } 15 16 func (v Vec2d) String() string { 17 return fmt.Sprintf("%f,%f", v.x, v.y) 18 } 19 20 /** 21 * Calculates the magnitude of a 2D cartesian vector. 22 * @param v The 2D cartesian vector. 23 * @return The magnitude of the vector. 24 */ 25 func _v2dMag(v *Vec2d) float64 { return math.Sqrt(v.x*v.x + v.y*v.y) } 26 27 /** 28 * Finds the intersection between two lines. Assumes that the lines intersect 29 * and that the intersection is not at an endpoint of either line. 30 * @param p0 The first endpoint of the first line. 31 * @param p1 The second endpoint of the first line. 32 * @param p2 The first endpoint of the second line. 33 * @param p3 The second endpoint of the second line. 34 * @param inter The intersection point. 35 */ 36 func _v2dIntersect(p0 *Vec2d, p1 *Vec2d, p2 *Vec2d, p3 *Vec2d, inter *Vec2d) { 37 var s1, s2 Vec2d 38 39 s1.x = p1.x - p0.x 40 s1.y = p1.y - p0.y 41 s2.x = p3.x - p2.x 42 s2.y = p3.y - p2.y 43 44 t := (s2.x*(p0.y-p2.y) - s2.y*(p0.x-p2.x)) / (-s2.x*s1.y + s1.x*s2.y) 45 46 inter.x = p0.x + (t * s1.x) 47 inter.y = p0.y + (t * s1.y) 48 } 49 50 /** 51 * Whether two 2D vectors are equal. Does not consider possible false 52 * negatives due to floating-point errors. 53 * @param v1 First vector to compare 54 * @param v2 Second vector to compare 55 * @return Whether the vectors are equal 56 */ 57 func _v2dEquals(v1 *Vec2d, v2 *Vec2d) bool { 58 return floatEqual(v1.x, v2.x) && floatEqual(v1.y, v2.y) 59 } 60 61 func floatEqual(a float64, b float64) bool { 62 return nearlyEqual(a, b, 1e-9) 63 } 64 65 func nearlyEqual(a float64, b float64, epsilon float64) bool { 66 if a == b { 67 return true 68 } 69 70 diff := math.Abs(a - b) 71 72 if diff < epsilon { 73 return true 74 } 75 76 return diff <= epsilon*math.Min(math.Abs(a), math.Abs(b)) 77 } 78 79 func normalizeDegree(v float64, min float64, max float64) float64 { 80 d := max - min 81 r := (v - min) / d 82 return min + (r-float64(int64(r)))*d 83 }