def _circular_coplanar_circular(self, other): cc = other.point - self.point d = cc.magnitude() rS = self.radius rO = other.radius # too far apart? if (rS + rO) < d - EPSILON: return Nowhere() # equal or circumscribed? if zero(d): if equal(rS, rO): return self return Nowhere() # tangent? if equal(d, rS + rO): cc = cc.magnitude(rS) return Unity(self.point + cc) # find the midpoint where the "radical line" (chord) crosses cc term = d * d - rS * rS + rO * rO xS = term / 2 * d xO = d - xS # find the length of the radical line leg = 4 * d * d * rS * rS - term * term yy = 1 / d * sqrt(leg) y = yy / 2 # find the intersection points cross = cc * self.normal chord = cc * cross chord = chord.magnitude(y) mark = cc mark = mark.magnitude(xS) mark += self.point return Duality(mark + chord, mark - chord)
def __test__(): from testing import __ok__, __report__ import vectors ; from vectors import V,equal,zero print 'Testing interpolations...' __ok__( linear(0.5, 50, 60), 55 ) __ok__( linear(1, 2, 1.5, 50, 60), 55 ) __ok__( linear(1, 2, 1.5, V(50,500), V(60,600)), V(55,550) ) __ok__( bezier3(0.0, 0.0, 1.0, 0.0), 0.0 ) __ok__( bezier3(0.5, 0.0, 1.0, 0.0), 0.5 ) __ok__( equal( bezier3(0.2, 0.0, 1.0, 0.0), bezier3(0.8, 0.0, 1.0, 0.0) ) ) __ok__( bezier3(1.0, 0.0, 1.0, 0.0), 0.0 ) __ok__( bezier4(0.0, 0.0, 1.0, 1.0, 0.0), 0.0 ) __ok__( bezier4(0.5, 0.0, 1.0, 1.0, 0.0), 0.75 ) __ok__( equal( bezier4(0.2, 0.0, 1.0, 1.0, 0.0), bezier4(0.8, 0.0, 1.0, 1.0, 0.0) ) ) __ok__( bezier4(1.0, 0.0, 1.0, 1.0, 0.0), 0.0 ) __ok__( bezier(0.0, 0.0, 1.0, 1.0, 1.0, 0.0), 0.0 ) __ok__( bezier(0.5, 0.0, 1.0, 1.0, 1.0, 0.0), 0.875 ) __ok__( equal( bezier(0.2, 0.0, 1.0, 1.0, 1.0, 0.0), bezier(0.8, 0.0, 1.0, 1.0, 1.0, 0.0) ) ) __ok__( bezier(1.0, 0.0, 1.0, 1.0, 1.0, 0.0), 0.0 ) __ok__( bezier(1.0, 0.0, 1.0, 1.0, 1.0, 0.0), 0.0 ) __report__()
def _circular_circular_test(): from testing import __ok__ # tangent at origin c1 = Circular(V(-1, 0, 0), V.Y, 1) c2 = Circular(V(1, 0, 0), V.Y, 1) c1c2 = c1 * c2 __ok__(isinstance(c1c2, Unity)) __ok__(c1c2.point == V()) # cross off origin c1 = Circular(V.O, V.Y, 1) c2 = Circular(V.X, V.Y, 1) c1c2 = c1 * c2 __ok__(isinstance(c1c2, Duality)) __ok__(c1c2.pointA[0] == c1c2.pointB[0]) __ok__(equal(c1c2.pointA[1], -c1c2.pointB[1])) __ok__(equal(abs(c1c2.pointA[1]), 0.5 * sqrt(3)))
def _planar_linear_test(): from testing import __ok__ p = Planar(V(3, 0, -1), V(0, 3, 0)) __ok__(str(p) == "Planar(V(3.0, 0.0, -1.0), V(0.0, 1.0, 0.0))") l = Linear(V(2, 1, 1), V(0, -1, 1)) u = p * l __ok__(str(u) == "Unity(V(1.0, 0.0, 1.0))") p = Planar(V(3, -7, -1), V(1, 1, 0)) __ok__(equal(sqrt(2) / 2, p.normal[1]))
def _spherical_spherical(self, other): cc = other.point - self.point d = cc.magnitude() rS = self.radius rO = other.radius # too far apart? if (rS + rO) < d - EPSILON: return Nowhere() # equal or circumscribed? if zero(d): if equal(rS, rO): return self return Nowhere() # tangent? if equal(d, rS + rO): cc = cc.magnitude(rS) return Unity(self.point + cc) if max(rS, rO) - (d + min(rO, rS)) > 0: #One sphere included in another return Nowhere() # find the midpoint where the "radical line" (chord) crosses cc #print d,rS,rO #print rS - (d+rO) term = d * d - rS * rS + rO * rO #print term #term = rS*rS - rO*rO xS = term / (2 * d) #print xS xO = d - xS # find the length of the radical line #leg = 4*d*d*rS*rS - term*term #yy = 1/d * sqrt(leg) #y = yy/2 y = sqrt(rS * rS - xO * xO) # find the intersection points cc.normalize() #print cc,xS mark = cc mark = mark.magnitude(xO) mark += self.point return Circular(mark, cc, y)
def _planar_planar_test(): from testing import __ok__ p = Planar(V(3, 0, -1), V(0, 3, 0)) q = Planar(V(5, 0, -5), V(1, 1, 0)) pq = p * q __ok__(isinstance(pq, Linear)) __ok__(equal(pq.pointB[1], pq.pointA[1])) q = Planar(V(5, 0, -5), V(0, 1, 0)) pq = p * q __ok__(pq is p) q = Planar(V(5, 1, -5), V(0, 1, 0)) pq = p * q __ok__(isinstance(pq, Nowhere))
def _circular_planar_test(): from testing import __ok__ # coplanar c = Circular(V(-1, 0, 0), V.Y, 1) p = Planar(V(1, 0, 0), V.Y) cp = c * p __ok__(cp is c) # parallel planar c = Circular(V(-1, 0, 0), V.Y, 1) p = Planar(V(1, 1, 0), V.Y) cp = c * p __ok__(isinstance(cp, Nowhere)) # grab the tangent c = Circular(V(0, 0, 0), V.Y, 1) p = Planar(V(0, 1, 0), V(1, 1, 0)) cp = c * p __ok__(isinstance(cp, Unity)) __ok__(equal(cp.point[0], 1)) # grab a duality c = Circular(V(0, 0, 0), V.Y, 1) p = Planar(V(0, .5, 0), V(1, 1, 0)) cp = c * p __ok__(isinstance(cp, Duality)) __ok__(equal(abs(cp.pointA[2]), 0.5 * sqrt(3)))
def is_point_on_line(la, dir, p): if not zero(dir[0]): alpha = (p[0] - la[0]) / dir[0] y = dir[1] * alpha + la[1] z = dir[2] * alpha + la[2] return equal(y, p[1]) and equal(z, p[2]) elif not zero(dir[1]): alpha = (p[1] - la[1]) / dir[1] z = dir[2] * alpha + la[2] return equal(la[0], p[0]) and equal(z, p[2]) elif not zero(dir[2]): # else: return equal(la[0], p[0]) and equal(la[1], p[1]) return False
def is_point_on_sphere(center, r, p): return equal(r, center.distance(p))