コード例 #1
0
 def __init__(self, pointA, pointB):
     Constraint.__init__(self)
     if pointA == pointB:
         raise ValueError, 'A Linear must refer to two different points.'
     self.pointA = V(pointA)
     self.pointB = V(pointB)
     self.dir = self.pointB - self.pointA
コード例 #2
0
def closest_point_on_circle(center, normal, radius, p):
    planar = closest_point_on_plane(center, normal, p)
    spoke = planar - center
    if not spoke: spoke = V(1, 0, 0) * normal
    if not spoke: spoke = V(0, 1, 0) * normal
    spoke = spoke.magnitude(radius)
    return center + spoke
コード例 #3
0
 def __init__(self, point, normal, radius):
     Constraint.__init__(self)
     if zero(radius):
         raise ValueError, 'A circle must have a non-zero radius.'
     self.point = V(point)
     self.normal = V(normal).normalize()
     self.radius = abs(float(radius))
     self.d = self.normal.dot(self.point)
コード例 #4
0
def _circular_linear_test():
    from testing import __ok__
    c = Circular(V(), V.Y, 1)
    l = Linear(V.Y, V(2, -1, 0))
    __ok__(str(c * l) == "Unity(V(1.0, 0.0, 0.0))")
    l = Linear(V.Y, -V.Y)
    __ok__(str(c * l) == "Nowhere()")
    l = Linear(V(0.5, 0, 0.5), V(0.5, 0, -0.5))
    cl = c * l
    __ok__(isinstance(cl, Duality))
    __ok__(cl.pointA[0] == cl.pointB[0])
コード例 #5
0
 def get_random(self):
     if self.normal[0] != 0 or self.normal[1] != 0:
         x0 = V(-self.normal[1], self.normal[0], 0)
     else:
         x0 = V(-self.normal[2], 0, self.normal[0])
     x0 = x0.normalize()
     self.normal = self.normal.normalize()
     x1 = self.normal.cross(x0)
     alpha = 2 * math.pi * random.random()
     return self.point + self.radius * (x0 * math.cos(alpha) +
                                        x1 * math.sin(alpha))
コード例 #6
0
 def generate_N(self, N):
     if self.normal[0] != 0 or self.normal[1] != 0:
         x0 = V(-self.normal[1], self.normal[0], 0)
     else:
         x0 = V(-self.normal[2], 0, self.normal[0])
     x0 = x0.normalize()
     self.normal = self.normal.normalize()
     x1 = self.normal.cross(x0)
     alphas = [(2 * 3.1415 * i) / N for i in range(N)]
     return [
         self.point + self.radius *
         (x0 * math.cos(alpha) + x1 * math.sin(alpha)) for alpha in alphas
     ]
コード例 #7
0
 def _planar_planar(self, other):
     crossSO = self.normal * other.normal
     # are we coplanar (Planar) or parallel (Nowhere)?
     if crossSO.zero():
         if self.accepts(other.point): return self
         return Nowhere()
     # find the intersection (Linear)
     dir = crossSO
     point = V()
     if not zero(crossSO[2]):
         point[0] = (other.normal[1] * self.d -
                     self.normal[1] * other.d) / crossSO[2]
         point[1] = (self.normal[0] * other.d -
                     other.normal[0] * self.d) / crossSO[2]
         point[2] = 0.0
     elif not zero(crossSO[1]):
         point[0] = (self.normal[2] * other.d -
                     other.normal[2] * self.d) / crossSO[1]
         point[1] = 0.0
         point[2] = (other.normal[0] * self.d -
                     self.normal[0] * other.d) / crossSO[1]
     elif not zero(crossSO[0]):  # else:
         point[0] = 0.0
         point[1] = (other.normal[1] * self.d -
                     self.normal[1] * other.d) / crossSO[0]
         point[2] = (self.normal[0] * other.d -
                     other.normal[0] * self.d) / crossSO[0]
     return Linear(point, point + dir)
コード例 #8
0
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)))
コード例 #9
0
    def get_random(self):

        phi = 2 * math.pi * random.random()
        theta = math.pi * random.random()
        return self.point + self.radius * (V([
            math.sin(theta) * math.cos(phi),
            math.sin(theta) * math.sin(phi),
            math.cos(theta)
        ]))
コード例 #10
0
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))
コード例 #11
0
 def _spherical_linear(self, other):
     mark = other.closest(self.point)
     aa = mark.dsquared(self.point)
     cc = self.radius * self.radius
     if aa > cc + EPSILON:
         return Nowhere()
     if aa < cc - EPSILON:
         chord = V(other.dir)
         b = sqrt(cc - aa)
         chord = chord.magnitude(b)
         return Duality(mark + chord, mark - chord)
     return Unity(mark)
コード例 #12
0
 def _circular_coplanar_linear(self, other):
     # might find unity, might find duality, might find nowhere
     mark = other.closest(self.point)
     aa = mark.dsquared(self.point)
     cc = self.radius * self.radius
     if aa > cc + EPSILON:
         return Nowhere()
     if aa < cc - EPSILON:
         chord = V(other.dir)
         b = sqrt(cc - aa)
         chord = chord.magnitude(b)
         return Duality(mark + chord, mark - chord)
     return Unity(mark)
コード例 #13
0
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]))
コード例 #14
0
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)))
コード例 #15
0
 def __init__(self, point):
     Constraint.__init__(self)
     self.point = V(point)
コード例 #16
0
def _linear_linear_test():
    from testing import __ok__
    # simple intersect at origin, commutative checks
    u = V(-1, 0, 0)
    v = -u
    c1 = Linear(u, v)
    r = V(0, -1, 0)
    s = -r
    c2 = Linear(r, s)
    __ok__(str(c1 * c2) == "Unity(V(0.0, 0.0, 0.0))")
    __ok__(str(c2 * c1) == "Unity(V(0.0, 0.0, 0.0))")
    c1 = Linear(v, u)
    __ok__(str(c1 * c2) == "Unity(V(0.0, 0.0, 0.0))")
    __ok__(str(c2 * c1) == "Unity(V(0.0, 0.0, 0.0))")
    # intersect away from origin
    o = V(0.125, 0.25, 0.5)
    u = V(-2, 3, -4)
    v = -u
    u += o
    v += o
    c1 = Linear(u, v)
    r = V(-3, 8, 21)
    s = -r
    r += o
    s += o
    c2 = Linear(r, s)
    __ok__(str(c2 * c1) == str(Unity(o)))
    __ok__(str(c1 * c2) == str(Unity(o)))
    # non-intersecting
    u = V(-1, 0, 0)
    v = -u
    u += V(0.0, 0.0, 0.5)
    v += V(0.0, 0.0, 0.5)
    c1 = Linear(u, v)
    r = V(0, -1, 0)
    s = -r
    c2 = Linear(r, s)
    __ok__(str(c1 * c2) == "Nowhere()")
    # intersecting
    r += 0.5
    s += 0.5
    c2 = Linear(r, s)
    __ok__(str(c1 * c2) == "Unity(V(0.5, 0.0, 0.5))")
    # colinear
    u = s + V(0, 0.5, 0)
    v = r + V(0, 0.5, 0)
    c1 = Linear(u, v)
    __ok__(str(c1 * c2) == str(c1))
コード例 #17
0
 def __init__(self, point, radius):
     Constraint.__init__(self)
     if zero(radius):
         raise ValueError, 'A sphere must have a non-zero radius.'
     self.point = V(point)
     self.radius = abs(float(radius))
コード例 #18
0
def closest_point_on_sphere(center, r, p):
    dir = p - center
    if dir.zero():
        return center + V(r, 0, 0)
    dir = dir.magnitude(r)
    return center + dir
コード例 #19
0
 def __init__(self, point, normal):
     Constraint.__init__(self)
     self.point = V(point)
     self.normal = V(normal).normalize()
     self.d = self.normal.dot(self.point)
コード例 #20
0
 def __init__(self, pointA, pointB):
     Constraint.__init__(self)
     if pointA == pointB:
         raise ValueError, 'Duality must refer to two different points.'
     self.pointA = V(pointA)
     self.pointB = V(pointB)