Example #1
0
// 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)))
	}
}
Example #2
0
// 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)
}
Example #3
0
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))
}
Example #4
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))
}
Example #6
0
// 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
}
Example #7
0
// 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()
}
Example #8
0
// 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
}
Example #9
0
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
}
Example #10
0
// 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
}
Example #11
0
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
}
Example #12
0
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
}
Example #13
0
/*
	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)
}
Example #14
0
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)
}
Example #15
0
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))
}
Example #16
0
// 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)
}
Example #17
0
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
}
Example #18
0
// 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
}
Example #19
0
// 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
}
Example #20
0
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)
}
Example #21
0
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)}
}
Example #22
0
// 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
}
Example #23
0
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}
}
Example #24
0
// 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
}
Example #25
0
// 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
}
Example #26
0
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)
}
Example #27
0
// 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
}
Example #28
0
// 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)
}
Example #29
0
func ExampleIlluminated_venus() {
	// Example 41.a, p. 284.
	k := base.Illuminated(math.Acos(.29312))
	fmt.Printf("%.3f\n", k)
	// Output:
	// 0.647
}
Example #30
0
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
}