示例#1
0
 def projection(self, obj):
     assert isinstance(
         obj, baseGeometryObject), 'incorrect object for projection'
     if isinstance(obj, Line):
         # TODO: remove 0.0 for future Python 3.X versions
         tmp = dot(self - obj.basePoint, obj.direction)
         if isinstance(tmp, oofun): tmp.size = 1
         tmp1 = obj.direction * tmp / (0.0 + sum(obj.direction**2))
         tmp2 = obj.basePoint
         if type(tmp1) == ooarray:  # hence tmp2 is array
             tmp2 = tmp2.view(ooarray)
         return Point(tmp1 + tmp2)
     elif isinstance(obj, Plane):
         d1, d2 = obj.directions
         bp = obj.basePoint
         a = sum(d1**2)
         b = d = dot(d1, d2)
         e = sum(d2**2)
         c = dot(self - bp, d1)
         f = dot(self - bp, d2)
         delta = a * e - b * d + 0.0  # TODO: remove 0.0 when Python 2.x will be deprecated
         alpha = (c * e - b * f) / delta
         beta = (a * f - c * d) / delta
         return Point(bp + alpha * d1 + beta * d2)
     else:
         raise SpaceFuncsException(
             'not implemented for this geometry object yet')
示例#2
0
 def projection(self, obj):
     assert isinstance(obj, baseGeometryObject), 'incorrect object for projection'
     if isinstance(obj, Line):
         # TODO: remove 0.0 for future Python 3.X versions
         tmp = dot(self-obj.basePoint, obj.direction)
         if isinstance(tmp, oofun): tmp.size = 1
         tmp1 = obj.direction*tmp / (0.0+sum(obj.direction**2))
         tmp2 = obj.basePoint
         if type(tmp1) == ooarray: # hence tmp2 is array
             tmp2 = tmp2.view(ooarray)
         return Point(tmp1+tmp2)
     elif isinstance(obj, Plane):
         d1, d2 = obj.directions
         bp = obj.basePoint
         a = sum(d1**2)
         b = d = dot(d1, d2)
         e = sum(d2**2)
         c = dot(self-bp, d1)
         f =  dot(self-bp, d2)
         delta = a*e-b*d + 0.0 # TODO: remove 0.0 when Python 2.x will be deprecated
         alpha = (c*e-b*f) / delta
         beta = (a*f-c*d)/delta
         return Point(bp + alpha * d1 + beta * d2)
     else:    
         raise SpaceFuncsException('not implemented for this geometry object yet')
示例#3
0
 def _centroid(self):
     tmp = [v.weight is not None for v in self.vertices]
     if all(tmp):
         return sum([v*v.weight for  v in self.vertices]) / sum([v.weight for v in self.vertices])
     elif not any(tmp):
         return sum(self.vertices)/ float(self.nVertices)
     else:
         assert 0, 'to get centroid you should either provide weight for all vertices or for noone'
示例#4
0
def skewLinesNearestPoints(line1, line2):
    assert isinstance(line1, Line) and isinstance(line2, Line)
    p1, p2 = line1.basePoint, line2.basePoint
    d1, d2 = line1.direction, line2.direction
    Delta = sum(d1**2)*sum(d2**2) - dot(d1, d2)**2
    Delta1 = dot(d2, p1-p2) * dot(d1, d2) - dot(d1, p1-p2) * sum(d2**2)
    Delta2 = dot(d2, p1-p2) * sum(d1**2) - dot(d1, d2) * dot(d1, p1-p2)
    t1 = Delta1 / Delta
    t2 = Delta2 / Delta
    for t in [t1, t2]:
        if isinstance(t, oofun): t.size = 1
    return Point(p1+t1*d1), Point(p2+t2*d2)
示例#5
0
def skewLinesNearestPoints(line1, line2):
    assert isinstance(line1, Line) and isinstance(line2, Line)
    p1, p2 = line1.basePoint, line2.basePoint
    d1, d2 = line1.direction, line2.direction
    Delta = sum(d1**2) * sum(d2**2) - dot(d1, d2)**2
    Delta1 = dot(d2, p1 - p2) * dot(d1, d2) - dot(d1, p1 - p2) * sum(d2**2)
    Delta2 = dot(d2, p1 - p2) * sum(d1**2) - dot(d1, d2) * dot(d1, p1 - p2)
    t1 = Delta1 / Delta
    t2 = Delta2 / Delta
    for t in [t1, t2]:
        if isinstance(t, oofun): t.size = 1
    return Point(p1 + t1 * d1), Point(p2 + t2 * d2)
示例#6
0
class Polygon(Polytope):
    _AttributesDict = Polytope._AttributesDict.copy()

    def __init__(self, *args, **kw):
        Polytope.__init__(self, *args, **kw)

    _sides = lambda self: ooarray([sqrt(sum((p1-p2)**2), attachConstraints=False) \
                                             for p1, p2 in \
                                             [(self.vertices[i], self.vertices[i+1]) for i in range(self.nVertices-1)] \
                                             + [(self.vertices[self.nVertices-1], self.vertices[0])]])

    _perimeter = lambda self: sum(self.sides)
    _semiperimeter = lambda self: 0.5 * self.P

    _angles = lambda self: ooarray([angle(p1, p2) for p1, p2 in \
                                             [(self.vertices[i-1]-self.vertices[i], self.vertices[i+1]-self.vertices[i]) for i in range(self.nVertices-1)]+\
                                             [(self.vertices[self.nVertices-2]-self.vertices[self.nVertices-1], self.vertices[0]-self.vertices[self.nVertices-1])]])

    def _area(self):
        D = self._spaceDimension()
        if isscalar(D) and D != 2:
            raise SpaceFuncsException(
                'polygon area is not implemented for space dimension > 2 yet')
        x, y = self._coords(0), self._coords(1)
        x.append(x[0])
        y.append(y[0])
        x, y = ooarray(x), ooarray(y)
        return 0.5 * abs(sum(x[:-1] * y[1:] - x[1:] * y[:-1]))

    def plot(self, *args, **kw):
        if not pylabInstalled:
            raise SpaceFuncsException(
                'to plot you should have matplotlib installed')
        #pylab.Line2D.__init__([self.vertices[i][0] for i in range(3)], [self.vertices[i][1] for i in range(3)])
        #raise 0
        pylab.plot([
            self.vertices[i][0]
            for i in (arange(self.nVertices).tolist() + [0])
        ], [
            self.vertices[i][1]
            for i in (arange(self.nVertices).tolist() + [0])
        ], *args, **kw)
        for i in range(3):
            self.vertices[i].plot()
        pylab.draw()

    __call__ = lambda self, *args, **kw: Polygon(
        [self.vertices[i](*args, **kw) for i in range(self.nVertices)])
示例#7
0
 def distance(self, *args, **kw):
     assert len(kw) == 0 and len(args) == 1
     other = args[0]
     if isinstance(other, (list, tuple)):
         other = Point(other)
     if isinstance(other, (Line, Plane)):
         return self.distance(self.projection(other))
     elif isinstance(other, ndarray):
         return sqrt(sum((self-other)**2), attachConstraints = False)
示例#8
0
 def _area(self):
     D = self._spaceDimension()
     if isscalar(D) and D != 2:
         raise SpaceFuncsException('polygon area is not implemented for space dimension > 2 yet')
     x, y = self._coords(0), self._coords(1)
     x.append(x[0])
     y.append(y[0])
     x, y = ooarray(x), ooarray(y)
     return 0.5*abs(sum(x[:-1]*y[1:] - x[1:]*y[:-1]))
示例#9
0
 def distance(self, *args, **kw):
     assert len(kw) == 0 and len(args) == 1
     other = args[0]
     if isinstance(other, (list, tuple)):
         other = Point(other)
     if isinstance(other, (Line, Plane)):
         return self.distance(self.projection(other))
     elif isinstance(other, ndarray):
         return sqrt(sum((self - other)**2), attachConstraints=False)
示例#10
0
 def _area(self):
     D = self._spaceDimension()
     if isscalar(D) and D != 2:
         raise SpaceFuncsException(
             'polygon area is not implemented for space dimension > 2 yet')
     x, y = self._coords(0), self._coords(1)
     x.append(x[0])
     y.append(y[0])
     x, y = ooarray(x), ooarray(y)
     return 0.5 * abs(sum(x[:-1] * y[1:] - x[1:] * y[:-1]))
示例#11
0
class Triangle(Polygon):
    #vertices = None
    nVertices = 3
    _AttributesDict = Polygon._AttributesDict.copy()

    def __init__(self, *args, **kw):
        assert len(kw) == 0 and len(args) in (1, 3)
        Polygon.__init__(self, *args, **kw)

    __call__ = lambda self, *args, **kw: Triangle(
        [self.vertices[i](*args, **kw) for i in range(self.nVertices)])

    _sides = lambda self: ooarray([sqrt(sum((p1- p2)**2), attachConstraints=False) for p1, p2 in \
                                    ((self.vertices[1], self.vertices[2]),
                                    (self.vertices[2], self.vertices[0]),
                                    (self.vertices[0], self.vertices[1]))])

    _angles = lambda self: ooarray([angle(p1, p2) for p1, p2 in \
                                    ((self.vertices[1]-self.vertices[0], self.vertices[2]-self.vertices[0]),
                                    (self.vertices[2]-self.vertices[1], self.vertices[0]-self.vertices[1]),
                                    (self.vertices[0]-self.vertices[2], self.vertices[1]-self.vertices[2]))])

    _area = lambda self: Polygon._area(self) if self._spaceDimension(
    ) is 2 else self._areaViaGeron()
    #_area = lambda self: Polygon._area(self) if self._spaceDimension() is 2 else self._areaViaHeightSideMult()

    _areaViaGeron = lambda self: sqrt(self.p * (self.p - self.sides[0]) *
                                      (self.p - self.sides[1]) *
                                      (self.p - self.sides[2]),
                                      attachConstraints=False)

    def _areaViaHeightSideMult(self):
        proj = self.vertices[0].projection(
            Line(self.vertices[1], self.vertices[2]))
        return 0.5 * proj.distance(
            self.vertices[0]) * self.vertices[1].distance(self.vertices[2])

    _circumCircleRadius = lambda self: (self.sides[0] * self.sides[1] * self.
                                        sides[2]) / (4 * self.S)

    _inscribedCircleRadius = lambda self: self.S / self.p

    _incenter = lambda self: (self.vertices[0] * self.sides[0] + self.vertices[
        1] * self.sides[1] + self.vertices[2] * self.sides[2]) / self.P

    _orthocenter = lambda self: self.vertices[0].perpendicular(Line(self.vertices[1], self.vertices[2])) \
    & self.vertices[1].perpendicular(Line(self.vertices[0], self.vertices[2]))

    # Eiler's theorem: 2 * vector(OM) = vector(MH) => O = M -0.5 MH = M - 0.5(H-M) = 1.5M - 0.5H
    _circumCircleCenter = lambda self: 1.5 * self.M - 0.5 * self.H

    _InscribedCircle = lambda self: Circle(self.I, self.r)
    _CircumCircle = lambda self: Circle(self.O, self.R)
示例#12
0
 def _circumSphereCenter(self):
     a, b, c = self.reducedVertices
     bc, ca, ab = self.reducedVerticesCrossProduct
     return (sum(a**2) * bc + sum(b**2) * ca + sum(c**2) * ab) / (2.0*dot(a, bc)) + self.vertices[-1]
示例#13
0
 def _circumSphereRadius(self):
     a, b, c = self.reducedVertices
     bc, ca, ab = self.reducedVerticesCrossProduct
     return norm(sum(a**2)*bc + sum(b**2)*ca + sum(c**2)*ab) / (12.0 * self.V)