func (p Place) BackAzimuth(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) sdlon := math.Sin(rdlon) ybaz := -sdlon * clat1 xbaz := clat2*slat1 - slat2*clat1*cdlon baz := RadiansToDegrees * math.Atan2(ybaz, xbaz) if baz < 0.0 { baz += 360.0 } return baz }
func (view *ViewData) Initialize() { twoPi := 8.0 * math.Atan(1.0) halfCone := float64(view.FieldOfView) * float64(twoPi/360.0) / 2.0 adjustedHalfCone := math.Asin(float64(view.ScreenWidth) * math.Sin(halfCone) / float64(view.StandardScreenWidth)) var worldToScreen float64 view.HalfScreenWidth = view.ScreenWidth / 2 view.HalfScreenHeight = view.ScreenHeight / 2 // if there's a round-off error in half_cone, we want to make the cone too big (so when we clip lines to the edge of the screen they're actually off the screen, thus +1.0) view.HalfCone = Angle(adjustedHalfCone*(float64(NumberOfAngles))/twoPi + 1.0) // calculate world_to_screen; we could calculate this with standard_screen_width/2 and the old half_cone and get the same result worldToScreen = float64(view.HalfScreenWidth) / math.Tan(adjustedHalfCone) tmp0 := int16((worldToScreen / float64(view.HorizontalScale)) + 0.5) tmp1 := int16((worldToScreen / float64(view.VerticalScale)) + 0.5) view.WorldToScreen.X = tmp0 view.RealWorldToScreen.X = tmp0 view.WorldToScreen.Y = tmp1 view.RealWorldToScreen.Y = tmp1 // cacluate the vertical cone angle; again, overflow instead of underflow when rounding view.HalfVerticalCone = Angle(NumberOfAngles*math.Atan((float64(view.HalfScreenHeight*view.VerticalScale)/worldToScreen))/twoPi + 1.0) // calculate left edge vector view.UntransformedLeftEdge.I = WorldDistance(view.WorldToScreen.X) view.UntransformedLeftEdge.J = WorldDistance(-view.HalfScreenWidth) // calculate right edge vector (negative, so it clips in the right direction) view.UntransformedRightEdge.I = WorldDistance(-view.WorldToScreen.X) view.UntransformedRightEdge.J = WorldDistance(-view.HalfScreenWidth) // reset any effects view.Effect = cseries.None }
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) }
func (p Place) Azimuth(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) sdlon := math.Sin(rdlon) yazi := sdlon * clat2 xazi := clat1*slat2 - slat1*clat2*cdlon azi := RadiansToDegrees * math.Atan2(yazi, xazi) if azi < 0.0 { azi += 360.0 } return azi }
// AnomalyDistance returns true anomaly and distance for near-parabolic orbits. // // Distance r returned in AU. // An error is returned if the algorithm fails to converge. func (e *Elements) AnomalyDistance(jde float64) (ν unit.Angle, r float64, err error) { // fairly literal translation of code on p. 246 q1 := base.K * math.Sqrt((1+e.Ecc)/e.PDis) / (2 * e.PDis) // line 20 g := (1 - e.Ecc) / (1 + e.Ecc) // line 20 t := jde - e.TimeP // line 22 if t == 0 { // line 24 return 0, e.PDis, nil } d1, d := 10000., 1e-9 // line 14 q2 := q1 * t // line 28 s := 2. / (3 * math.Abs(q2)) // line 30 s = 2 / math.Tan(2*math.Atan(math.Cbrt(math.Tan(math.Atan(s)/2)))) if t < 0 { // line 34 s = -s } if e.Ecc != 1 { // line 36 l := 0 // line 38 for { s0 := s // line 40 z := 1. y := s * s g1 := -y * s q3 := q2 + 2*g*s*y/3 // line 42 for { z += 1 // line 44 g1 = -g1 * g * y // line 46 z1 := (z - (z+1)*g) / (2*z + 1) // line 48 f := z1 * g1 // line 50 q3 += f // line 52 if z > 50 || math.Abs(f) > d1 { // line 54 return 0, 0, errors.New("No convergence") } if math.Abs(f) <= d { // line 56 break } } l++ // line 58 if l > 50 { return 0, 0, errors.New("No convergence") } for { s1 := s // line 60 s = (2*s*s*s/3 + q3) / (s*s + 1) if math.Abs(s-s1) <= d { // line 62 break } } if math.Abs(s-s0) <= d { // line 64 break } } } ν = unit.Angle(2 * math.Atan(s)) // line 66 r = e.PDis * (1 + e.Ecc) / (1 + e.Ecc*ν.Cos()) // line 68 if ν < 0 { // line 70 ν += 2 * math.Pi } return }
func (pt *Point) cartesianToGeographic(meridien float64, a float64, e float64, eps float64) { x := pt.X y := pt.Y z := pt.Z lon := meridien + math.Atan(y/x) module := math.Sqrt(x*x + y*y) phi_0 := math.Atan(z / (module * (1 - (a*e*e)/math.Sqrt(x*x+y*y+z*z)))) phi_i := math.Atan(z / module / (1 - a*e*e*math.Cos(phi_0)/(module*math.Sqrt(1-e*e*math.Sin(phi_0)*math.Sin(phi_0))))) delta := 100.0 for delta > eps { phi_0 = phi_i phi_i = math.Atan(z / module / (1 - a*e*e*math.Cos(phi_0)/(module*math.Sqrt(1-e*e*math.Sin(phi_0)*math.Sin(phi_0))))) delta = math.Abs(phi_i - phi_0) } he := module/math.Cos(phi_i) - a/math.Sqrt(1-e*e*math.Sin(phi_i)*math.Sin(phi_i)) pt.X = lon pt.Y = phi_i pt.Z = he pt.Unit = Radian }
func (sfc *pdfSurface) Skew(xRadians float64, yRadians float64) { x := math.Atan(xRadians) y := math.Atan(yRadians) sfc.alterMatrix(1, x, y, 1, 0, 0) }
func (self *Calc) CalculateFunction(funcName string, arg32 float32) float32 { if len(self.errors) > 0 { return 1 } var result float64 arg := float64(arg32) switch funcName { case "sin": result = math.Sin(self.DegToRad(arg)) case "cos": result = math.Cos(self.DegToRad(arg)) case "tg": result = math.Tan(self.DegToRad(arg)) case "ctg": result = 1.0 / math.Tan(self.DegToRad(arg)) case "arcsin": result = self.RadToDeg(math.Asin(arg)) case "arccos": result = self.RadToDeg(math.Acos(arg)) case "arctg": result = self.RadToDeg(math.Atan(arg)) case "arcctg": result = self.RadToDeg(math.Atan(1 / arg)) case "sqrt": result = math.Sqrt(arg) default: self.errors = append(self.errors, "Unknown identifier "+funcName) return 1 } return float32(result) }
// ProbContestSmall computes the probability for a contest between u and v where u wins if it's // the smaller value. φ ∃ [0,1] is a scaling factor that helps v win even if it's not smaller. // If φ==0, deterministic analysis is carried out. If φ==1, probabilistic analysis is carried out. // As φ → 1, v "gets more help". func ProbContestSmall(u, v, φ float64) float64 { u = math.Atan(u)/math.Pi + 1.5 v = math.Atan(v)/math.Pi + 1.5 if u < v { return v / (v + φ*u) } if u > v { return φ * v / (φ*v + u) } return 0.5 }
// Get matrix rotation as Euler angles in degrees func (m *Mat3) GetEuler() *V3 { x := math.Atan((-m.matrix[5]) / m.matrix[8]) y := math.Asin(m.matrix[2]) z := math.Atan((-m.matrix[1]) / m.matrix[0]) // Convert to Degrees x *= 180 / math.Pi y *= 180 / math.Pi z *= 180 / math.Pi return NewV3(x, y, z) }
// Get M rotation as Euler angles in degrees func (m *Mat3) GetEuler() *Vec3 { x := math.Atan((-m.M[5]) / m.M[8]) y := math.Asin(m.M[2]) z := math.Atan((-m.M[1]) / m.M[0]) // Convert to Degrees x *= 180 / math.Pi y *= 180 / math.Pi z *= 180 / math.Pi return V3(x, y, z) }
func latitudeFromLatitudeISO(lat_iso float64, e float64, eps float64) float64 { phi_0 := 2*math.Atan(math.Exp(lat_iso)) - math.Pi/2 phi_i := 2*math.Atan(math.Pow((1+e*math.Sin(phi_0))/(1-e*math.Sin(phi_0)), e/2)*math.Exp(lat_iso)) - math.Pi/2 delta := 100.0 for delta > eps { phi_0 = phi_i phi_i = 2*math.Atan(math.Pow((1+e*math.Sin(phi_0))/(1-e*math.Sin(phi_0)), e/2.0)*math.Exp(lat_iso)) - math.Pi/2 delta = math.Abs(phi_i - phi_0) } return phi_i }
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)) }
/** * Returns the yaw pitch and roll angles, respectively defined as the angles in radians between * the Earth North and the IMU Z axis (yaw), the Earth ground plane and the IMU Y axis (pitch) * and the Earth ground plane and the IMU X axis (roll). * * Returns Yaw, Pitch and Roll angles in radians **/ func (imu *ImuMayhony) Update(when int64, gx, gy, gz, ax, ay, az, mx, my, mz float32) (yaw, pitch, roll float32) { var ( gravx, gravy, gravz float64 // estimated gravity direction ) imu.sampleFreq = 1.0 / (float32(when-imu.lastUpdate) / 1000000000.0) // nanoseconds to fractions of a second imu.lastUpdate = when ahrsUpdate(imu, gx, gy, gz, ax, ay, az, mx, my, mz) gravx = float64(2.0 * (imu.q1*imu.q3 - imu.q0*imu.q2)) gravy = float64(2.0 * (imu.q0*imu.q1 + imu.q2*imu.q3)) gravz = float64(imu.q0*imu.q0 - imu.q1*imu.q1 - imu.q2*imu.q2 + imu.q3*imu.q3) yaw = float32(math.Atan2(float64(2.0*imu.q1*imu.q2-2.0*imu.q0*imu.q3), float64(2.0*imu.q0*imu.q0+2.0*imu.q1*imu.q1-1.0))) pitch = float32(math.Atan(gravx / math.Sqrt(gravy*gravy+gravz*gravz))) roll = float32(math.Atan(gravy / math.Sqrt(gravx*gravx+gravz*gravz))) return }
//GridToGeodetic converts RT90 coordinates to WGS84 func GridToGeodetic(x, y float64) (float64, float64) { if CentralMeridian == 31337.0 { return 0.0, 0.0 } e2 := Flattening * (2.0 - Flattening) n := Flattening / (2.0 - Flattening) a_roof := Axis / (1.0 + n) * (1.0 + n*n/4.0 + n*n*n*n/64.0) delta1 := n/2.0 - 2.0*n*n/3.0 + 37.0*n*n*n/96.0 - n*n*n*n/360.0 delta2 := n*n/48.0 + n*n*n/15.0 - 437.0*n*n*n*n/1440.0 delta3 := 17.0*n*n*n/480.0 - 37*n*n*n*n/840.0 delta4 := 4397.0 * n * n * n * n / 161280.0 Astar := e2 + e2*e2 + e2*e2*e2 + e2*e2*e2*e2 Bstar := -(7.0*e2*e2 + 17.0*e2*e2*e2 + 30.0*e2*e2*e2*e2) / 6.0 Cstar := (224.0*e2*e2*e2 + 889.0*e2*e2*e2*e2) / 120.0 Dstar := -(4279.0 * e2 * e2 * e2 * e2) / 1260.0 DegToRad := math.Pi / 180 LambdaZero := CentralMeridian * DegToRad xi := (x - FalseNorthing) / (Scale * a_roof) eta := (y - FalseEasting) / (Scale * a_roof) xi_prim := xi - delta1*math.Sin(2.0*xi)*math.Cosh(2.0*eta) - delta2*math.Sin(4.0*xi)*math.Cosh(4.0*eta) - delta3*math.Sin(6.0*xi)*math.Cosh(6.0*eta) - delta4*math.Sin(8.0*xi)*math.Cosh(8.0*eta) eta_prim := eta - delta1*math.Cos(2.0*xi)*math.Sinh(2.0*eta) - delta2*math.Cos(4.0*xi)*math.Sinh(4.0*eta) - delta3*math.Cos(6.0*xi)*math.Sinh(6.0*eta) - delta4*math.Cos(8.0*xi)*math.Sinh(8.0*eta) phi_star := math.Asin(math.Sin(xi_prim) / math.Cosh(eta_prim)) delta_lambda := math.Atan(math.Sinh(eta_prim) / math.Cos(xi_prim)) lon_radian := LambdaZero + delta_lambda lat_radian := phi_star + math.Sin(phi_star)*math.Cos(phi_star)*(Astar+Bstar*math.Pow(math.Sin(phi_star), 2)+Cstar*math.Pow(math.Sin(phi_star), 4)+Dstar*math.Pow(math.Sin(phi_star), 6)) return lat_radian * 180.0 / math.Pi, lon_radian * 180.0 / math.Pi }
func fromPixelToLL(px [2]float64, zoom uint64) [2]float64 { e := gp.zc[zoom] f := (px[0] - e[0]) / gp.Bc[zoom] g := (px[1] - e[1]) / -gp.Cc[zoom] h := 180.0 / math.Pi * (2*math.Atan(math.Exp(g)) - 0.5*math.Pi) return [2]float64{f, h} }
// PointArea returns the area on the unit sphere for the triangle defined by the // given points. // // This method is based on l'Huilier's theorem, // // tan(E/4) = sqrt(tan(s/2) tan((s-a)/2) tan((s-b)/2) tan((s-c)/2)) // // where E is the spherical excess of the triangle (i.e. its area), // a, b, c are the side lengths, and // s is the semiperimeter (a + b + c) / 2. // // The only significant source of error using l'Huilier's method is the // cancellation error of the terms (s-a), (s-b), (s-c). This leads to a // *relative* error of about 1e-16 * s / min(s-a, s-b, s-c). This compares // to a relative error of about 1e-15 / E using Girard's formula, where E is // the true area of the triangle. Girard's formula can be even worse than // this for very small triangles, e.g. a triangle with a true area of 1e-30 // might evaluate to 1e-5. // // So, we prefer l'Huilier's formula unless dmin < s * (0.1 * E), where // dmin = min(s-a, s-b, s-c). This basically includes all triangles // except for extremely long and skinny ones. // // Since we don't know E, we would like a conservative upper bound on // the triangle area in terms of s and dmin. It's possible to show that // E <= k1 * s * sqrt(s * dmin), where k1 = 2*sqrt(3)/Pi (about 1). // Using this, it's easy to show that we should always use l'Huilier's // method if dmin >= k2 * s^5, where k2 is about 1e-2. Furthermore, // if dmin < k2 * s^5, the triangle area is at most k3 * s^4, where // k3 is about 0.1. Since the best case error using Girard's formula // is about 1e-15, this means that we shouldn't even consider it unless // s >= 3e-4 or so. func PointArea(a, b, c Point) float64 { sa := float64(b.Angle(c.Vector)) sb := float64(c.Angle(a.Vector)) sc := float64(a.Angle(b.Vector)) s := 0.5 * (sa + sb + sc) if s >= 3e-4 { // Consider whether Girard's formula might be more accurate. dmin := s - math.Max(sa, math.Max(sb, sc)) if dmin < 1e-2*s*s*s*s*s { // This triangle is skinny enough to use Girard's formula. ab := a.PointCross(b) bc := b.PointCross(c) ac := a.PointCross(c) area := math.Max(0.0, float64(ab.Angle(ac.Vector)-ab.Angle(bc.Vector)+bc.Angle(ac.Vector))) if dmin < s*0.1*area { return area } } } // Use l'Huilier's formula. return 4 * math.Atan(math.Sqrt(math.Max(0.0, math.Tan(0.5*s)*math.Tan(0.5*(s-sa))* math.Tan(0.5*(s-sb))*math.Tan(0.5*(s-sc))))) }
func TestCapContainsCell(t *testing.T) { faceRadius := math.Atan(math.Sqrt2) for face := 0; face < 6; face++ { // The cell consisting of the entire face. rootCell := CellFromCellID(CellIDFromFace(face)) // A leaf cell at the midpoint of the v=1 edge. edgeCell := CellFromPoint(Point{faceUVToXYZ(face, 0, 1-eps)}) // A leaf cell at the u=1, v=1 corner cornerCell := CellFromPoint(Point{faceUVToXYZ(face, 1-eps, 1-eps)}) // Quick check for full and empty caps. if !full.ContainsCell(rootCell) { t.Errorf("Cap(%v).ContainsCell(%v) = %t; want = %t", full, rootCell, false, true) } // Check intersections with the bounding caps of the leaf cells that are adjacent to // cornerCell along the Hilbert curve. Because this corner is at (u=1,v=1), the curve // stays locally within the same cube face. first := cornerCell.id.Advance(-3) last := cornerCell.id.Advance(4) for id := first; id < last; id = id.Next() { c := CellFromCellID(id).CapBound() if got, want := c.ContainsCell(cornerCell), id == cornerCell.id; got != want { t.Errorf("Cap(%v).ContainsCell(%v) = %t; want = %t", c, cornerCell, got, want) } } for capFace := 0; capFace < 6; capFace++ { // A cap that barely contains all of capFace. center := unitNorm(capFace) covering := CapFromCenterAngle(center, s1.Angle(faceRadius+eps)) if got, want := covering.ContainsCell(rootCell), capFace == face; got != want { t.Errorf("Cap(%v).ContainsCell(%v) = %t; want = %t", covering, rootCell, got, want) } if got, want := covering.ContainsCell(edgeCell), center.Vector.Dot(edgeCell.id.Point().Vector) > 0.1; got != want { t.Errorf("Cap(%v).ContainsCell(%v) = %t; want = %t", covering, edgeCell, got, want) } if got, want := covering.ContainsCell(edgeCell), covering.IntersectsCell(edgeCell); got != want { t.Errorf("Cap(%v).ContainsCell(%v) = %t; want = %t", covering, edgeCell, got, want) } if got, want := covering.ContainsCell(cornerCell), capFace == face; got != want { t.Errorf("Cap(%v).ContainsCell(%v) = %t; want = %t", covering, cornerCell, got, want) } // A cap that barely intersects the edges of capFace. bulging := CapFromCenterAngle(center, s1.Angle(math.Pi/4+eps)) if bulging.ContainsCell(rootCell) { t.Errorf("Cap(%v).ContainsCell(%v) = %t; want = %t", bulging, rootCell, true, false) } if got, want := bulging.ContainsCell(edgeCell), capFace == face; got != want { t.Errorf("Cap(%v).ContainsCell(%v) = %t; want = %t", bulging, edgeCell, got, want) } if bulging.ContainsCell(cornerCell) { t.Errorf("Cap(%v).ContainsCell(%v) = %t; want = %t", bulging, cornerCell, true, false) } } } }
// Generates sample from general Levy-stable distibution. func Sample(alpha float64, beta float64, mu float64, sigma float64) float64 { if beta == 0.0 { return symmetric(alpha, mu, sigma) } v := math.Pi * (rand.Float64() - 0.5) w := 0.0 for w == 0.0 { w = rand.ExpFloat64() } if alpha == 1.0 { x := ((0.5*math.Pi+beta*v)*math.Tan(v) - beta*math.Log(0.5*math.Pi*w*math.Cos(v)/(0.5*math.Pi+beta*v))) / (0.5 * math.Pi) return sigma*x + beta*sigma*math.Log(sigma)/(0.5*math.Pi) + mu } t := beta * math.Tan(0.5*math.Pi*alpha) s := math.Pow(1.0+t*t, 1.0/(2.0*alpha)) b := math.Atan(t) / alpha x := s * math.Sin(alpha*(v+b)) * math.Pow(math.Cos(v-alpha*(v+b))/w, (1.0-alpha)/alpha) / math.Pow(math.Cos(v), 1.0/alpha) return sigma*x + mu }
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 (p *PerspectiveCamera) UpdateProjectionMatrix() { var fov = math3d.RadToDeg(2 * math.Atan(math.Tan(math3d.DegToRad(p.Fov)*0.5)/p.Zoom)) if p.FullWidth > 0 { var aspect = p.FullWidth / p.FullHeight var top = math.Tan(math3d.DegToRad(fov*0.5)) * p.Near var bottom = -top var left = aspect * bottom var right = aspect * top var width = math.Abs(right - left) var height = math.Abs(top - bottom) p.ProjectionMatrix.MakeFrustum( left+p.X*width/p.FullWidth, left+(p.X+p.Width)*width/p.FullWidth, top-(p.Y+p.Height)*height/p.FullHeight, top-p.Y*height/p.FullHeight, p.Near, p.Far, ) } else { p.ProjectionMatrix.MakePerspective(fov, p.Aspect, p.Near, p.Far) } }
// ParallaxConstants computes parallax constants ρ sin φ′ and ρ cos φ′. // // Arguments are geographic latitude φ in radians and height h // in meters above the ellipsoid. func (e Ellipsoid) ParallaxConstants(φ, h float64) (s, c float64) { boa := 1 - e.Fl su, cu := math.Sincos(math.Atan(boa * math.Tan(φ))) s, c = math.Sincos(φ) hoa := h * 1e-3 / e.Er return su*boa + hoa*s, cu + hoa*c }
// ParallaxConstants computes parallax constants ρ sin φ′ and ρ cos φ′. // // Arguments are geographic latitude φ and height h above the ellipsoid. // For e.Er in Km, h must be in meters. func (e Ellipsoid) ParallaxConstants(φ unit.Angle, h float64) (s, c float64) { boa := 1 - e.Fl su, cu := math.Sincos(math.Atan(boa * φ.Tan())) s, c = φ.Sincos() hoa := h * 1e-3 / e.Er return su*boa + hoa*s, cu + hoa*c }
func (pdf *PdfBergstrom) ScaledValue(x, alpha, beta float64) (float64, error) { var err error zeta := beta * math.Tan(0.5*math.Pi*alpha) eps := pdf.eps / x * math.Pi done := false n := 1 sum := 0.0 for !done { a := 1.0 if n%2 == 0 { a = -1.0 } a *= math.Gamma(float64(n)*alpha+1) / math.Gamma(float64(n)+1) a *= math.Pow(1+zeta*zeta, 0.5*float64(n)) a *= math.Sin(float64(n) * (0.5*math.Pi*alpha + math.Atan(zeta))) delta := a * math.Pow(x, -alpha*float64(n)) sum += delta if math.Abs(delta) < eps { done = true } if n >= pdf.limit { done = true err = fmt.Errorf("Iteration limit in tail approximation exceeded (%d)", pdf.limit) } n++ } sum /= x * math.Pi return sum, err }
func (v *Vec3) ToSpherical() (c *SphVec3) { // from Wikipedia article c.r = v.Length() c.phi = math.Atan2(v.y, v.x) c.theta = math.Atan(v.z / c.r) return }
// Write text on line from p1 to p2, with cntGrids values as given in vals. // Prerequisites: vals[] is linear func (s *SVG) Label(x1, y1, x2, y2 int, vals []float64, cntGrids int, a Att) { g := s.GID("label", a) g.AddAtt(false, Att{"fill": "black"}) xDiff := float64(x2 - x1) yDiff := float64(y2 - y1) angle := math.Abs(math.Atan(yDiff / xDiff)) // Find increments max := max(vals...) min := min(vals...) valIncr := (max - min) / float64(cntGrids) xIncr := float64(xDiff) / float64(cntGrids) * math.Cos(angle) yIncr := float64(yDiff) / float64(cntGrids) * math.Sin(angle) // Start values val := min x := float64(x1) y := float64(y1) // Draw text for i := 0; i <= cntGrids; i++ { g.Text(round(x), round(y), fmt.Sprintf("%.2f", val), nil) val += valIncr x += xIncr y += yIncr } }
func xatan() { r := popr() if r< -math.Pi/2+paminstr.Eps || r>math.Pi/2-paminstr.Eps { panic("atan argument out of [-Pi/2, Pi/2]") } pushr(math.Atan(r)) }
// Generate a warped frequency curve for warping coefficient _alpha_ // and return a normalized vector of length _vectorlength_ containing // equally spaced points between 0 and PI func WarpingVector(alpha float64, vectorlength int) []float64 { var i int var step float64 var warpingvector []float64 step = math.Pi / float64(vectorlength) warpingvector = make([]float64, vectorlength, vectorlength) for i = 0; i < vectorlength; i++ { var warpfreq, omega float64 var num, den float64 omega = step * float64(i) num = (1 - alpha*alpha) * math.Sin(omega) den = (1+alpha*alpha)*math.Cos(omega) - 2*alpha warpfreq = math.Atan(num / den) // Wrap the phase if it becomes negative if warpfreq < 0 { warpfreq += math.Pi } warpingvector[i] = warpfreq } // Normalize the Vector. Values are positive and monotonically // increasing, so divide by max max := warpingvector[vectorlength-1] for i = 0; i < vectorlength; i++ { warpingvector[i] /= max } return warpingvector }
func convertLABToHue(a, b float64) float64 { var bias float64 = 0 if a >= 0 && b == 0 { return 0 } if a < 0 && b == 0 { return 180 } if a == 0 && b > 0 { return 90 } if a == 0 && b < 0 { return 270 } if a > 0 && b > 0 { bias = 0 } if a < 0 { bias = 180 } if a > 0 && b < 0 { bias = 360 } return (convertRadToDeg(math.Atan(b/a)) + bias) }
func asrTime(loc Location, julT, dhuhr, factor float64) float64 { _, dec := sunPosition(julT) angle := -math.Atan(1 / (factor + math.Tan(rad(math.Abs(loc.Lat-dec))))) aTime := timeAngle(loc.Lat, julT, dhuhr, angle, 1) //fmt.Println(angle, aTime) return aTime }