Esempio n. 1
0
def _perpendicularToLine(point, line):  #, **kw):
    ############################################
    # Don't change "is" by "=="!!!
    if point.size is 2 or line.basePoint.size is 2 or line.direction.size is 2:
        # thus 2D space is involved
        return Line(point,
                    direction=ooarray(line.direction[1], -line.direction[0]))
    ############################################
    projection = point.projection(line)
    if projection.dtype != object and all(
            projection.view(ndarray) == point.view(ndarray)):
        if 'size' not in dir(point) + dir(line.basePoint) + dir(
                line.direction):
            s = '''
            The point belongs to the line, hence
            to perform the operation safely you should provide 
            space dimension (as "size" parameter for 
            either point or line point or line direction).
            Assuming space dimension is 2 
            (elseware lots of perpendicular lines wrt the point and the line exist)
            '''
            pWarn(s)
        else:
            raise SpaceFuncsException(
                'for space dimension > 2 you should have point outside of the line'
            )
        return Line(point,
                    direction=ooarray(line.direction[1], -line.direction[0]))
    else:
        return Line(point, projection)
Esempio n. 2
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]))
Esempio n. 3
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]))
Esempio n. 4
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)
Esempio n. 5
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)])
Esempio n. 6
0
 def __new__(self, *args, **kw):
     self.pointCounter += 1
     self._num = asscalar(self.pointCounter)
     self.specifier = '.'
     self.color = 'k'
     Args = args[:-1] if type(args[-1]) == str else args
     r = asarray(Args[0]).view(self) if len(Args) == 1 and type(
         Args[0]) in (ooarray, Point, ndarray, list,
                      tuple) else ooarray(Args).view(self)
     r.name = args[-1] if type(args[-1]) == str else kw[
         'name'] if 'name' in kw else 'unnamed point ' + str(self._num)
     r._id = oofun._id
     oofun._id += 1
     return r
Esempio n. 7
0
def _perpendicularToLine(point, line): #, **kw):
    ############################################
    # Don't change "is" by "=="!!!
    if point.size is 2 or line.basePoint.size is 2 or line.direction.size is 2:
        # thus 2D space is involved
        return Line(point, direction=ooarray(line.direction[1], -line.direction[0]))
    ############################################
    projection = point.projection(line)
    if projection.dtype != object and all(projection.view(ndarray)==point.view(ndarray)):
        if 'size' not in dir(point) + dir(line.basePoint) + dir(line.direction):
            s = '''
            The point belongs to the line, hence
            to perform the operation safely you should provide 
            space dimension (as "size" parameter for 
            either point or line point or line direction).
            Assuming space dimension is 2 
            (elseware lots of perpendicular lines wrt the point and the line exist)
            '''
            pWarn(s)
        else:
            raise SpaceFuncsException('for space dimension > 2 you should have point outside of the line')
        return Line(point, direction=ooarray(line.direction[1], -line.direction[0]))
    else:
        return Line(point, projection)
Esempio n. 8
0
 def __new__(self, *args, **kw):
     self.pointCounter += 1
     self._num = asscalar(self.pointCounter)
     self.specifier = '.'
     self.color = 'k'
     Args = args[:-1] if type(args[-1]) == str else args
     r =  asarray(Args[0]).view(self) if len(Args) == 1 and type(Args[0]) in (ooarray, Point, ndarray, list, tuple) else ooarray(Args).view(self)
     r.name = args[-1] if type(args[-1]) == str else kw['name'] if 'name' in kw else 'unnamed point ' + str(self._num)
     r._id = oofun._id
     oofun._id += 1
     return r