本文整理匯總了Golang中github.com/golang/geo/r3.Vector類的典型用法代碼示例。如果您正苦於以下問題:Golang Vector類的具體用法?Golang Vector怎麽用?Golang Vector使用的例子?那麽, 這裏精選的類代碼示例或許可以為您提供幫助。
在下文中一共展示了Vector類的4個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: TrueCentroid
// TrueCentroid returns the true centroid of the spherical triangle ABC multiplied by the
// signed area of spherical triangle ABC. The result is not normalized.
// The reasons for multiplying by the signed area are (1) this is the quantity
// that needs to be summed to compute the centroid of a union or difference of triangles,
// and (2) it's actually easier to calculate this way. All points must have unit length.
//
// The true centroid (mass centroid) is defined as the surface integral
// over the spherical triangle of (x,y,z) divided by the triangle area.
// This is the point that the triangle would rotate around if it was
// spinning in empty space.
//
// The best centroid for most purposes is the true centroid. Unlike the
// planar and surface centroids, the true centroid behaves linearly as
// regions are added or subtracted. That is, if you split a triangle into
// pieces and compute the average of their centroids (weighted by triangle
// area), the result equals the centroid of the original triangle. This is
// not true of the other centroids.
func TrueCentroid(a, b, c Point) Point {
ra := float64(1)
if sa := float64(b.Distance(c)); sa != 0 {
ra = sa / math.Sin(sa)
}
rb := float64(1)
if sb := float64(c.Distance(a)); sb != 0 {
rb = sb / math.Sin(sb)
}
rc := float64(1)
if sc := float64(a.Distance(b)); sc != 0 {
rc = sc / math.Sin(sc)
}
// Now compute a point M such that:
//
// [Ax Ay Az] [Mx] [ra]
// [Bx By Bz] [My] = 0.5 * det(A,B,C) * [rb]
// [Cx Cy Cz] [Mz] [rc]
//
// To improve the numerical stability we subtract the first row (A) from the
// other two rows; this reduces the cancellation error when A, B, and C are
// very close together. Then we solve it using Cramer's rule.
//
// This code still isn't as numerically stable as it could be.
// The biggest potential improvement is to compute B-A and C-A more
// accurately so that (B-A)x(C-A) is always inside triangle ABC.
x := r3.Vector{a.X, b.X - a.X, c.X - a.X}
y := r3.Vector{a.Y, b.Y - a.Y, c.Y - a.Y}
z := r3.Vector{a.Z, b.Z - a.Z, c.Z - a.Z}
r := r3.Vector{ra, rb - ra, rc - ra}
return Point{r3.Vector{y.Cross(z).Dot(r), z.Cross(x).Dot(r), x.Cross(y).Dot(r)}.Mul(0.5)}
}
示例2: RobustSign
// RobustSign returns a Direction representing the ordering of the points.
// CounterClockwise is returned if the points are in counter-clockwise order,
// Clockwise for clockwise, and Indeterminate if any two points are the same (collinear),
// or the sign could not completely be determined.
//
// This function has additional logic to make sure that the above properties hold even
// when the three points are coplanar, and to deal with the limitations of
// floating-point arithmetic.
//
// RobustSign satisfies the following conditions:
//
// (1) RobustSign(a,b,c) == 0 if and only if a == b, b == c, or c == a
// (2) RobustSign(b,c,a) == RobustSign(a,b,c) for all a,b,c
// (3) RobustSign(c,b,a) == -RobustSign(a,b,c) for all a,b,c
//
// In other words:
//
// (1) The result is zero if and only if two points are the same.
// (2) Rotating the order of the arguments does not affect the result.
// (3) Exchanging any two arguments inverts the result.
//
// On the other hand, note that it is not true in general that
// RobustSign(-a,b,c) == -RobustSign(a,b,c), or any similar identities
// involving antipodal points.
//
// C++ Equivalent: RobustCCW()
func RobustSign(a, b, c Point) Direction {
// This method combines the computations from the C++ methods
// RobustCCW, TriageCCW, ExpensiveCCW, and StableCCW.
// TODO: Split these extra functions out when the need arises.
// Start with TriageCCW
det := c.Cross(a.Vector).Dot(b.Vector)
if det > maxDeterminantError {
return CounterClockwise
}
if det < -maxDeterminantError {
return Clockwise
}
// ExpensiveCCW
if a == b || b == c || c == a {
return Indeterminate
}
// StableCCW
ab := a.Sub(b.Vector)
ab2 := ab.Norm2()
bc := b.Sub(c.Vector)
bc2 := bc.Norm2()
ca := c.Sub(a.Vector)
ca2 := ca.Norm2()
// The two shortest edges, pointing away from their common point.
var e1, e2, op r3.Vector
if ab2 >= bc2 && ab2 >= ca2 {
// AB is the longest edge.
e1, e2, op = ca, bc, c.Vector
} else if bc2 >= ca2 {
// BC is the longest edge.
e1, e2, op = ab, ca, a.Vector
} else {
// CA is the longest edge.
e1, e2, op = bc, ab, b.Vector
}
det = e1.Cross(e2).Dot(op)
maxErr := detErrorMultiplier * math.Sqrt(e1.Norm2()*e2.Norm2())
// If the determinant isn't zero, we know definitively the point ordering.
if det > maxErr {
return CounterClockwise
}
if det < -maxErr {
return Clockwise
}
// In the C++ version, the final computation is performed using OpenSSL's
// Bignum exact precision math library. The existence of an equivalent
// library in Go is indeterminate. In C++, using the exact precision library
// to solve this stage is ~300x slower than the above checks.
// TODO(roberts): Select and incorporate an appropriate Go exact precision
// floating point library for the remaining calculations.
return Indeterminate
}
示例3: face
// face returns face ID from 0 to 5 containing the r. For points on the
// boundary between faces, the result is arbitrary but deterministic.
func face(r r3.Vector) int {
abs := r.Abs()
id := 0
value := r.X
if abs.Y > abs.X {
id = 1
value = r.Y
}
if abs.Z > math.Abs(value) {
id = 2
value = r.Z
}
if value < 0 {
id += 3
}
return id
}
示例4: stableSign
// stableSign reports the direction sign of the points in a numerically stable way.
// Unlike triageSign, this method can usually compute the correct determinant sign even when all
// three points are as collinear as possible. For example if three points are
// spaced 1km apart along a random line on the Earth's surface using the
// nearest representable points, there is only a 0.4% chance that this method
// will not be able to find the determinant sign. The probability of failure
// decreases as the points get closer together; if the collinear points are
// 1 meter apart, the failure rate drops to 0.0004%.
//
// This method could be extended to also handle nearly-antipodal points (and
// in fact an earlier version of this code did exactly that), but antipodal
// points are rare in practice so it seems better to simply fall back to
// exact arithmetic in that case.
func stableSign(a, b, c Point) Direction {
ab := a.Sub(b.Vector)
ab2 := ab.Norm2()
bc := b.Sub(c.Vector)
bc2 := bc.Norm2()
ca := c.Sub(a.Vector)
ca2 := ca.Norm2()
// Now compute the determinant ((A-C)x(B-C)).C, where the vertices have been
// cyclically permuted if necessary so that AB is the longest edge. (This
// minimizes the magnitude of cross product.) At the same time we also
// compute the maximum error in the determinant.
// The two shortest edges, pointing away from their common point.
var e1, e2, op r3.Vector
if ab2 >= bc2 && ab2 >= ca2 {
// AB is the longest edge.
e1, e2, op = ca, bc, c.Vector
} else if bc2 >= ca2 {
// BC is the longest edge.
e1, e2, op = ab, ca, a.Vector
} else {
// CA is the longest edge.
e1, e2, op = bc, ab, b.Vector
}
det := e1.Cross(e2).Dot(op)
maxErr := detErrorMultiplier * math.Sqrt(e1.Norm2()*e2.Norm2())
// If the determinant isn't zero, within maxErr, we know definitively the point ordering.
if det > maxErr {
return CounterClockwise
}
if det < -maxErr {
return Clockwise
}
return Indeterminate
}