// Get the angle in radians of the rotation this quaternion represents. Does not normalize the quaternion. Use // {@link #getAxisAngleRad(Vector3)} to get both the axis and the angle of this rotation. Use // {@link #getAngleAroundRad(Vector3)} to get the angle around a specific axis. // return the angle in radians of the rotation func (self *Quaternion) GetAngleRad() float32 { if self.w > 1 { return float32(2.0 * math.Acos(float64(self.w/self.Len()))) } else { return float32(2.0 * math.Acos(float64(self.w))) } }
// Aa gets the rotation of quaternion q as an axis and angle. // The axis (x, y, z) and the angle in radians is returned. // The return elements will be zero if the length of the quaternion is 0. // See: // http://web.archive.org/web/20041029003853/... // ...http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q57 func (q *Q) Aa() (ax, ay, az, angle float64) { sinSqr := 1 - q.W*q.W if AeqZ(sinSqr) { return 1, 0, 0, 2 * math.Acos(q.W) } sin := 1 / math.Sqrt(sinSqr) return q.X * sin, q.Y * sin, q.Z * sin, 2 * math.Acos(q.W) }
func main() { fmt.Println("cos(pi/2):", math.Cos(math.Pi/2)) fmt.Println("cos(0):", math.Cos(0)) fmt.Println("sen(pi/2):", math.Sin(math.Pi/2)) fmt.Println("sen(0):", math.Sin(0)) fmt.Println("arccos(1):", math.Acos(1)) fmt.Println("arccos(0):", math.Acos(0)) fmt.Println("arcsen(1):", math.Asin(1)) fmt.Println("arcsen(0):", math.Asin(0)) }
// CircleCircleIntersectionArea returns the intersection area of 2 circles. func CircleCircleIntersectionArea(a, b Circle) float64 { d := Dist(a.Point, b.Point) if Sign(d) <= 0 || d+a.R <= b.R || d+b.R <= a.R { return Sqr(math.Min(a.R, b.R)) * math.Pi } if d >= a.R+b.R { return 0 } da := (Sqr(d) + Sqr(a.R) - Sqr(b.R)) / d / 2 db := d - da return Sqr(a.R)*math.Acos(da/a.R) - da*math.Sqrt(Sqr(a.R)-Sqr(da)) + Sqr(b.R)*math.Acos(db/b.R) - db*math.Sqrt(Sqr(b.R)-Sqr(db)) }
func main() { fmt.Printf("sin(%9.6f deg) = %f\n", d, math.Sin(d*math.Pi/180)) fmt.Printf("sin(%9.6f rad) = %f\n", r, math.Sin(r)) fmt.Printf("cos(%9.6f deg) = %f\n", d, math.Cos(d*math.Pi/180)) fmt.Printf("cos(%9.6f rad) = %f\n", r, math.Cos(r)) fmt.Printf("tan(%9.6f deg) = %f\n", d, math.Tan(d*math.Pi/180)) fmt.Printf("tan(%9.6f rad) = %f\n", r, math.Tan(r)) fmt.Printf("asin(%f) = %9.6f deg\n", s, math.Asin(s)*180/math.Pi) fmt.Printf("asin(%f) = %9.6f rad\n", s, math.Asin(s)) fmt.Printf("acos(%f) = %9.6f deg\n", c, math.Acos(c)*180/math.Pi) fmt.Printf("acos(%f) = %9.6f rad\n", c, math.Acos(c)) fmt.Printf("atan(%f) = %9.6f deg\n", t, math.Atan(t)*180/math.Pi) fmt.Printf("atan(%f) = %9.6f rad\n", t, math.Atan(t)) }
// Distance returns the approximate distance from another point in kilometers. func (p Point) Distance(p2 Point) float64 { r := 6371.01 return math.Acos((math.Sin(p.RadLat())* math.Sin(p2.RadLat()))+ (math.Cos(p.RadLat())*math.Cos(p2.RadLat())* math.Cos(p.RadLon()-p2.RadLon()))) * r }
// Spherically interpolates between this vector and the target vector by alpha which is in the range [0,1]. The result is // stored in this vector. // target The target vector // alpha The interpolation coefficient. func (self *Vector3) Slerp(target *Vector3, alpha float32) *Vector3 { dot := self.DotV(target) // If the inputs are too close for comfort, simply linearly interpolate. if dot > 0.9995 || dot < -0.9995 { return self.Lerp(target, alpha) } // theta0 = angle between input vectors theta0 := float32(math.Acos(float64(dot))) // theta = angle between this vector and result theta := theta0 * alpha st := float32(math.Sin(float64(theta))) tx := target.X - self.X*dot ty := target.Y - self.Y*dot tz := target.Z - self.Z*dot l2 := tx*tx + ty*ty + tz*tz var dl float32 if l2 < 0.0001 { dl = st * 1 } else { dl = st * 1 / float32(math.Sqrt(float64(l2))) } return self.SclScalar(float32(math.Cos(float64(theta)))).Add(tx*dl, ty*dl, tz*dl).Nor() }
// Spherical linear interpolation. // t is the interpolation value from 0. to 1. // p and q are 'const'. m is *not* func (m Quaternion) Slerp(t float64, p, q Quaternion) Quaternion { cs := p.Dot(q) angle := math.Acos(cs) if math.Fabs(angle) >= internalε { sn := math.Sin(angle) invSn := 1. / sn tAngle := t * angle coeff0 := math.Sin(angle-tAngle) * invSn coeff1 := math.Sin(tAngle) * invSn m[0] = float64(coeff0*p[0] + coeff1*q[0]) m[1] = float64(coeff0*p[1] + coeff1*q[1]) m[2] = float64(coeff0*p[2] + coeff1*q[2]) m[3] = float64(coeff0*p[3] + coeff1*q[3]) } else { m[0] = p[0] m[1] = p[1] m[2] = p[2] m[3] = p[3] } return m }
func CreateSphere(o2w, w2o *Transform, ro bool, rad, z0, z1, pm float64) *Sphere { s := new(Sphere) s.objectToWorld = o2w s.worldToObject = w2o s.reverseOrientation = ro s.transformSwapsHandedness = SwapsHandednessTransform(s.objectToWorld) s.shapeId = GenerateShapeId() s.radius = rad s.Zmin = Clamp(math.Min(z0, z1), -s.radius, s.radius) s.Zmax = Clamp(math.Max(z0, z1), -s.radius, s.radius) s.thetaMin = math.Acos(Clamp(s.Zmin/s.radius, -1.0, 1.0)) s.thetaMax = math.Acos(Clamp(s.Zmax/s.radius, -1.0, 1.0)) s.phiMax = Radians(Clamp(pm, 0.0, 360.0)) return s }
// AstrometricJ2000 is a utility function for computing astrometric coordinates. // // It is used internally and only exported so that it can be used from // multiple packages. It is not otherwise expected to be used. // // Argument f is a function that returns J2000 equatorial rectangular // coodinates of a body. // // Results are J2000 right ascention, declination, and elongation. func AstrometricJ2000(f func(float64) (x, y, z float64), jde float64, e *pp.V87Planet) (α, δ, ψ float64) { X, Y, Z := solarxyz.PositionJ2000(e, jde) x, y, z := f(jde) // (33.10) p. 229 ξ := X + x η := Y + y ζ := Z + z Δ := math.Sqrt(ξ*ξ + η*η + ζ*ζ) { τ := base.LightTime(Δ) x, y, z = f(jde - τ) ξ = X + x η = Y + y ζ = Z + z Δ = math.Sqrt(ξ*ξ + η*η + ζ*ζ) } α = math.Atan2(η, ξ) if α < 0 { α += 2 * math.Pi } δ = math.Asin(ζ / Δ) R0 := math.Sqrt(X*X + Y*Y + Z*Z) ψ = math.Acos((ξ*X + η*Y + ζ*Z) / R0 / Δ) return }
func TestTofloat(t *testing.T) { oldval := cfg.UseRadians cfg.UseRadians = true type test struct { in string out float64 } var tests []test = []test{ {"2.5+2.5", 2.5 + 2.5}, {"2.5*2.5", 2.5 * 2.5}, {"3/2", 3. / 2.}, {"2^10", math.Pow(2, 10)}, {"sqrt(2)", math.Sqrt(2)}, {"sin(2)", math.Sin(2)}, {"cos(2)", math.Cos(2)}, {"tan(2)", math.Tan(2)}, {"arcsin(0.3)", math.Asin(0.3)}, {"arccos(0.3)", math.Acos(0.3)}, {"arctan(0.3)", math.Atan(0.3)}, {"ln(2)", math.Log(2)}, {"log(2)", math.Log10(2)}, } for _, k := range tests { result := TextToCas(k.in).Tofloat() if result != k.out { t.Errorf("Tofloat: In:%v Out:%v Result:%v", k.in, k.out, result) } } cfg.UseRadians = oldval }
func arc(t VertexConverter, x, y, rx, ry, start, angle, scale float64) (lastX, lastY float64) { end := start + angle clockWise := true if angle < 0 { clockWise = false } ra := (math.Abs(rx) + math.Abs(ry)) / 2 da := math.Acos(ra/(ra+0.125/scale)) * 2 //normalize if !clockWise { da = -da } angle = start + da var curX, curY float64 for { if (angle < end-da/4) != clockWise { curX = x + math.Cos(end)*rx curY = y + math.Sin(end)*ry return curX, curY } curX = x + math.Cos(angle)*rx curY = y + math.Sin(angle)*ry angle += da t.Vertex(curX, curY) } return curX, curY }
/* SphericalDistance calculates the distance (in meters) between two WGS84 points */ func SphericalDistance(lat1, lon1, lat2, lon2 float64) int { // Convert latitude and longitude to // spherical coordinates in radians. degrees_to_radians := math.Pi / 180.0 // phi = 90 - latitude phi1 := (90.0 - lat1) * degrees_to_radians phi2 := (90.0 - lat2) * degrees_to_radians // theta = longitude theta1 := lon1 * degrees_to_radians theta2 := lon2 * degrees_to_radians /* Compute spherical distance from spherical coordinates. For two locations in spherical coordinates (1, theta, phi) and (1, theta, phi) cosine( arc length ) = sin phi sin phi' cos(theta-theta') + cos phi cos phi' distance = rho * arc length */ cos := (math.Sin(phi1)*math.Sin(phi2)*math.Cos(theta1-theta2) + math.Cos(phi1)*math.Cos(phi2)) arc := math.Acos(cos) // Remember to multiply arc by the radius of the earth //in your favorite set of units to get length. return int(6373 * 1000 * arc) }
func main() { // Triangle Rectangle Tr := [3][2]float64{{0, 0}, {50, 0}, {50, 30}} // Sides a := Tr[2][0] - Tr[0][0] b := Tr[2][0] - Tr[0][0] c := M.Sqrt(M.Pow(a, 2) + M.Pow(b, 2)) // Reason of b over c, or // How many times c is b? bc := b / c ac := a / c // Angle in vertex Tr[0] ß := M.Asin(bc) println("Sin after Asin: ", M.Sin(ß), bc, M.Sin(ß) == bc) println("Cos after Asin: ", M.Cos(ß), ac, M.Cos(ß) == bc, M.Cos(ß)-bc) // Angle in vertex Tr[0] ß = M.Acos(ac) println("Sin after Acos: ", M.Sin(ß), bc, M.Sin(ß) == bc, M.Sin(ß)-bc) println("Cos after Acos: ", M.Cos(ß), ac, M.Cos(ß) == bc) }
func xacos() { r := popr() if r< -1-paminstr.Eps || r>1+paminstr.Eps { panic("acos argument out of [-1.0, 1.0]") } pushr(math.Acos(r)) }
// Distance2DLinePointAngular returns the angle the line segment a would have // to rotate about its midpoint to pass through point b. func Distance2DLinePointAngular(a *Line2D, b *Vector2D) float64 { mpx, mpy := a.P.X+0.5*a.V.X, a.P.Y+0.5*a.V.Y adx, ady := a.P.X-mpx, a.P.Y-mpy ldx, ldy := b.X-mpx, b.Y-mpy return math.Abs(math.Acos((adx*ldx+ady*ldy)/ math.Sqrt((adx*adx+ady*ady)*(ldx*ldx+ldy*ldy))) - math.Pi/2) }
func Angle(v1, v2 Vector) (float64, error) { d, err := Dot(Normalize(v1), Normalize(v2)) if err != nil { return 0, err } return math.Acos(d) * 180.0 / math.Pi, nil }
// Calculates (this quaternion)^alpha where alpha is a real number and stores the result in this quaternion. // See http://en.wikipedia.org/wiki/Quaternion#Exponential.2C_logarithm.2C_and_power // param alpha Exponent func (self *Quaternion) Exp(alpha float32) *Quaternion { //Calculate |q|^alpha norm := self.Len() normExp := float32(math.Pow(float64(norm), float64(alpha))) //Calculate theta theta := float32(math.Acos(float64(self.w / norm))) //Calculate coefficient of basis elements //If theta is small enough, use the limit of sin(alpha*theta) / sin(theta) instead of actual value var coeff float32 if math.Abs(float64(theta)) < 0.001 { coeff = normExp * alpha / norm } else { coeff = float32(float64(normExp) * math.Sin(float64(alpha*theta)/(float64(norm)*math.Sin(float64(theta))))) } //Write results self.w = float32((float64(normExp) * math.Cos(float64(alpha*theta)))) self.x *= coeff self.y *= coeff self.z *= coeff //Fix any possible discrepancies self.Nor() return self }
// Converts 3-dimensional cartesian coordinates (x,y,z) to spherical // coordinates with radius r, inclination theta, and azimuth phi. // // All angles are in radians. func CartesianToSpherical(coord Vec3) (r, theta, phi float64) { r = coord.Len() theta = float64(math.Acos(float64(coord[2] / r))) phi = float64(math.Atan2(float64(coord[1]), float64(coord[0]))) return }
func SegmentArc(t LineTracer, x, y, rx, ry, start, angle, scale float64) { end := start + angle clockWise := true if angle < 0 { clockWise = false } ra := (math.Abs(rx) + math.Abs(ry)) / 2 da := math.Acos(ra/(ra+0.125/scale)) * 2 //normalize if !clockWise { da = -da } angle = start + da var curX, curY float64 for { if (angle < end-da/4) != clockWise { curX = x + math.Cos(end)*rx curY = y + math.Sin(end)*ry return } curX = x + math.Cos(angle)*rx curY = y + math.Sin(angle)*ry angle += da t.LineTo(curX, curY) } t.LineTo(curX, curY) }
func arcAdder(adder raster.Adder, x, y, rx, ry, start, angle, scale float64) raster.Point { end := start + angle clockWise := true if angle < 0 { clockWise = false } ra := (math.Abs(rx) + math.Abs(ry)) / 2 da := math.Acos(ra/(ra+0.125/scale)) * 2 //normalize if !clockWise { da = -da } angle = start + da var curX, curY float64 for { if (angle < end-da/4) != clockWise { curX = x + math.Cos(end)*rx curY = y + math.Sin(end)*ry return raster.Point{raster.Fix32(curX * 256), raster.Fix32(curY * 256)} } curX = x + math.Cos(angle)*rx curY = y + math.Sin(angle)*ry angle += da adder.Add1(raster.Point{raster.Fix32(curX * 256), raster.Fix32(curY * 256)}) } return raster.Point{raster.Fix32(curX * 256), raster.Fix32(curY * 256)} }
// Horizontal computes data for a horizontal sundial. // // Argument φ is geographic latitude at which the sundial will be located, // a is the length of a straight stylus perpendicular to the plane of the // sundial. // // Results consist of a set of lines, a center point, and u, the length of a // polar stylus. They are in units of a, the stylus length. func Horizontal(φ, a float64) (lines []Line, center Point, u float64) { sφ, cφ := math.Sincos(φ) tφ := sφ / cφ for i := 0; i < 24; i++ { l := Line{Hour: i} H := float64(i-12) * 15 * math.Pi / 180 aH := math.Abs(H) sH, cH := math.Sincos(H) for _, d := range m { tδ := math.Tan(d * math.Pi / 180) H0 := math.Acos(-tφ * tδ) if aH > H0 { continue // sun below horizon } Q := cφ*cH + sφ*tδ x := a * sH / Q y := a * (sφ*cH - cφ*tδ) / Q l.Points = append(l.Points, Point{x, y}) } if len(l.Points) > 0 { lines = append(lines, l) } } center.Y = -a / tφ u = a / math.Abs(sφ) return }
func MakeCamera(points []Vector) Camera { up := Vector{0, 0, 1} var center Vector for _, point := range points { center = center.Add(point) } center = center.DivScalar(float64(len(points))) var eye Vector best := 1e9 for i := 0; i < 1000; i++ { v := RandomUnitVector().MulScalar(50) score := cameraScore(points, v) if score < best { best = score eye = v } } var fovy float64 c := center.Sub(eye).Normalize() for _, point := range points { d := point.Sub(eye).Normalize() a := Degrees(math.Acos(d.Dot(c)) * 2 * 1.2) fovy = math.Max(fovy, a) } return Camera{eye, center, up, fovy} }
// Equatorial computes data for a sundial level with the equator. // // Argument φ is geographic latitude at which the sundial will be located; // a is the length of a straight stylus perpendicular to the plane of the // sundial. // // The sundial will have two sides, north and south. Results n and s define // lines on the north and south sides of the sundial. Result coordinates // are in units of a, the stylus length. func Equatorial(φ, a float64) (n, s []Line) { tφ := math.Tan(φ) for i := 0; i < 24; i++ { nl := Line{Hour: i} sl := Line{Hour: i} H := float64(i-12) * 15 * math.Pi / 180 aH := math.Abs(H) sH, cH := math.Sincos(H) for _, d := range m { tδ := math.Tan(d * math.Pi / 180) H0 := math.Acos(-tφ * tδ) if aH > H0 { continue } x := -a * sH / tδ yy := a * cH / tδ if tδ < 0 { sl.Points = append(sl.Points, Point{x, yy}) } else { nl.Points = append(nl.Points, Point{x, -yy}) } } if len(nl.Points) > 0 { n = append(n, nl) } if len(sl.Points) > 0 { s = append(s, sl) } } return }
// AngleError returns both an angle as in the function Angle, and an error // as in the function Error. // // The algorithm is by B. Pessens. func AngleError(r1, d1, r2, d2, r3, d3 float64) (ψ, ω float64) { sr1, cr1 := math.Sincos(r1) sd1, cd1 := math.Sincos(d1) sr2, cr2 := math.Sincos(r2) sd2, cd2 := math.Sincos(d2) sr3, cr3 := math.Sincos(r3) sd3, cd3 := math.Sincos(d3) a1 := cd1 * cr1 a2 := cd2 * cr2 a3 := cd3 * cr3 b1 := cd1 * sr1 b2 := cd2 * sr2 b3 := cd3 * sr3 c1 := sd1 c2 := sd2 c3 := sd3 l1 := b1*c2 - b2*c1 l2 := b2*c3 - b3*c2 l3 := b1*c3 - b3*c1 m1 := c1*a2 - c2*a1 m2 := c2*a3 - c3*a2 m3 := c1*a3 - c3*a1 n1 := a1*b2 - a2*b1 n2 := a2*b3 - a3*b2 n3 := a1*b3 - a3*b1 ψ = math.Acos((l1*l2 + m1*m2 + n1*n2) / (math.Sqrt(l1*l1+m1*m1+n1*n1) * math.Sqrt(l2*l2+m2*m2+n2*n2))) ω = math.Asin((a2*l3 + b2*m3 + c2*n3) / (math.Sqrt(a2*a2+b2*b2+c2*c2) * math.Sqrt(l3*l3+m3*m3+n3*n3))) return }
func (p Place) Distance(point Place) float64 { if (p.Latitude == point.Latitude) && (p.Longitude == point.Longitude) { return 0.0 } esq := (1.0 - 1.0/298.25) * (1.0 - 1.0/298.25) alat3 := math.Atan(math.Tan(p.Latitude/RadiansToDegrees)*esq) * RadiansToDegrees alat4 := math.Atan(math.Tan(point.Latitude/RadiansToDegrees)*esq) * RadiansToDegrees rlat1 := alat3 / RadiansToDegrees rlat2 := alat4 / RadiansToDegrees rdlon := (point.Longitude - p.Longitude) / RadiansToDegrees clat1 := math.Cos(rlat1) clat2 := math.Cos(rlat2) slat1 := math.Sin(rlat1) slat2 := math.Sin(rlat2) cdlon := math.Cos(rdlon) cdel := slat1*slat2 + clat1*clat2*cdlon switch { case cdel > 1.0: cdel = 1.0 case cdel < -1.0: cdel = -1.0 } return RadiansToKm * math.Acos(cdel) }
// Vertical computes data for a vertical sundial. // // Argument φ is geographic latitude at which the sundial will be located. // D is gnomonic declination, the azimuth of the perpendicular to the plane // of the sundial, measured from the southern meridian towards the west. // Argument a is the length of a straight stylus perpendicular to the plane // of the sundial. // // Results consist of a set of lines, a center point, and u, the length of a // polar stylus. They are in units of a, the stylus length. func Vertical(φ, D, a float64) (lines []Line, center Point, u float64) { sφ, cφ := math.Sincos(φ) tφ := sφ / cφ sD, cD := math.Sincos(D) for i := 0; i < 24; i++ { l := Line{Hour: i} H := float64(i-12) * 15 * math.Pi / 180 aH := math.Abs(H) sH, cH := math.Sincos(H) for _, d := range m { tδ := math.Tan(d * math.Pi / 180) H0 := math.Acos(-tφ * tδ) if aH > H0 { continue // sun below horizon } Q := sD*sH + sφ*cD*cH - cφ*cD*tδ if Q < 0 { continue // sun below plane of sundial } x := a * (cD*sH - sφ*sD*cH + cφ*sD*tδ) / Q y := -a * (cφ*cH + sφ*tδ) / Q l.Points = append(l.Points, Point{x, y}) } if len(l.Points) > 0 { lines = append(lines, l) } } center.X = -a * sD / cD center.Y = a * tφ / cD u = a / math.Abs(cφ*cD) return }
// Distance3DLinePointAngular returns the angle the line segment a would have // to rotate about its midpoint to pass through point b. func Distance3DLinePointAngular(a *Line3D, b *Vector3D) float64 { mpx, mpy, mpz := a.P.X+a.V.X*0.5, a.P.Y+a.V.Y*0.5, a.P.Z+a.V.Z*0.5 adx, ady, adz := a.P.X-mpx, a.P.Y-mpy, a.P.Z-mpz ldx, ldy, ldz := b.X-mpx, b.Y-mpy, b.Z-mpz return math.Abs(math.Acos((adx*ldx+ady*ldy+adz*ldz)/ math.Sqrt((adx*adx+ady*ady+adz*adz)*(ldx*ldx+ldy*ldy+ldz*ldz))) - math.Pi/2) }
func ExampleIlluminated_venus() { // Example 41.a, p. 284. k := base.Illuminated(math.Acos(.29312)) fmt.Printf("%.3f\n", k) // Output: // 0.647 }
func (this *Quat) QSlerp(a, b *Quat, x float32) *Quat { ax, ay, az, aw := a[0], a[1], a[2], a[3] bx, by, bz, bw := b[0], b[1], b[2], b[3] cosom := ax*bx + ay*by + az*bz + aw*bw var omega, sinom, scale0, scale1 float32 if cosom < 0 { cosom *= -1 bx *= -1 by *= -1 bz *= -1 bw *= -1 } if 1-cosom > 0 { omega = float32(math.Acos(float64(cosom))) sinom = 1 / float32(math.Sin(float64(omega))) scale0 = float32(math.Sin(float64((1-x)*omega))) * sinom scale1 = float32(math.Sin(float64(x*omega))) * sinom } else { scale0 = 1 - x scale1 = x } this[0] = scale0*ax + scale1*bx this[1] = scale0*ay + scale1*by this[2] = scale0*az + scale1*bz this[3] = scale0*aw + scale1*bw return this }