def construct_spread(self, spread): """ Calculate the Vertex which meets this point and which creates a given spread with this line from both of its lines. """ #pylint: disable-msg=R0914 if self.line.null(): raise NullLineError if spread == 0: par = self.parallel() return Vertex(par, par) a, b, c = self.geometry.form x0, y0 = self.point.form() a1, b1, _ = self.line.form() U = self.line.vector() k = (1 - spread)*U.norm() # set up the parameters to solve # alpha * x^2 + beta * x * y + gamma * y^2 = 0 # if alpha == 0: # => b * x * y + gamma * y * y == 0 # y(b * x + gamma * y) == 0 # x/y == -gamma/beta alpha = (a*b1 - b*a1)*(a*b1 - b*a1) - k*a beta = 2*((a*b1 - b*a1)*(b*b1 - c*a1) - b*k) gamma = (b*b1 - c*a1)*(b*b1 - c*a1) - k*c if alpha == 0: a2 = alpha # = 0; We use alpha like this b2 = alpha + 1 # = 1; to maintain the field a3 = beta b3 = gamma else: det = beta*beta - 4*alpha*gamma a2 = a3 = 2*alpha b2 = beta + det.sqrt() b3 = beta - det.sqrt() c2 = -(a2*x0 + b2*y0) c3 = -(a3*x0 + b3*y0) l2 = Line(a2, b2, c2, self.geometry) l3 = Line(a3, b3, c3, self.geometry) assert PointLine(self.point, l2).on() assert PointLine(self.point, l3).on() assert Vertex(l2, l3).point == self.point or (l2 == l3 and spread == 1) assert Vertex(self.line, l2).spread() == spread or l2.null() assert Vertex(self.line, l3).spread() == spread or l3.null() return Vertex(l2, l3)
def test_repr(): f = Rational blue_ = blue(Rational) red_ = red(Rational) green_ = green(Rational) print blue_, red_, green_ print Point(f(1), f(2), None) print Point(f(1), f(2), blue_) print Line(f(1), f(2), f(3), None) print Line(f(1), f(2), f(3), blue_) print Conic(f(1), f(2), f(3), f(4), f(5), f(6), None) print Conic(f(1), f(2), f(3), f(4), f(5), f(6), blue_)
def add_line(self, evt): a = self.a.GetValue() b = self.b.GetValue() c = self.c.GetValue() name = self.name.GetValue() line = Line(self.field(a), self.field(b), self.field(c), self._get_colour()), name, "o", self.colours.GetValue() self.parent.object_panel.add_line(line)
def __init__(self, point1, point2): """ Create a new line segment from two points. Both points must be of the same geometry or else a GeometryError will be raised. """ self.point1 = point1 self.point2 = point2 if point1.geometry != point2.geometry: raise GeometryError self.geometry = point1.geometry x1, y1 = point1.form() x2, y2 = point2.form() self.line = Line(y1 - y2, x2 - x1, x1*y2 - x2*y1, self.geometry)
def test_construct_quadrance(): f = FiniteField f.base = 37 geom = blue(f) line = Line(f(1), f(1), f(10), geom) point = Point(f(0), f(1), geom) pl = PointLine(point, line) X = pl.construct_quadrance(f(10)) v = pl.construct_spread(f(1) / f(5)) N = 20 for data in generate_fuzz_data(N, pointlines=1, spreads=1): pl = data.pointlines[0] s = data.spreads[0] try: ls = pl.construct_quadrance(s) except ValueError: pass
def test_construct_spread(): f = FiniteField f.base = 7 geom = blue(f) line = Line(f(0), f(1), f(0), geom) point = Point(f(1), f(2), geom) pl = PointLine(point, line) v = pl.construct_spread(f(1) / f(5)) N = 20 for data in generate_fuzz_data(N, pointlines=1, spreads=1): pl = data.pointlines[0] s = data.spreads[0] if pl.line.null(): assert_raises(NullLineError, pl.construct_spread, s) else: try: v = pl.construct_spread(s) except ValueError: pass
class LineSegment(object): """ A linesegment represents a pair of points. """ def __init__(self, point1, point2): """ Create a new line segment from two points. Both points must be of the same geometry or else a GeometryError will be raised. """ self.point1 = point1 self.point2 = point2 if point1.geometry != point2.geometry: raise GeometryError self.geometry = point1.geometry x1, y1 = point1.form() x2, y2 = point2.form() self.line = Line(y1 - y2, x2 - x1, x1*y2 - x2*y1, self.geometry) def __eq__(self, other): return (self.point1 in [other.point1, other.point2] and self.point2 in [other.point1, other.point2] and self.geometry == other.geometry) @check_geometry def midpoint(self): """ Return the midpoint M of the two points of the line segments so that Q(M, point1) == Q(M, point2). """ line0 = self.perp_bisector() # Find where the equidistant line intersects our line return Vertex(self.line, line0).point @check_geometry def perp_bisector(self): """ Return the perpindicular bisector of the two points. """ x1, y1 = self.point1.form() x2, y2 = self.point2.form() a, b, c = self.geometry.form # Calculate the line of equidistant points a0 = 2*(a*(x1 - x2) + b*(y1 - y2)) b0 = 2*(b*(x1 - x2) + c*(y1 - y2)) c0 = -(a*(x1*x1 - x2*x2) + 2*b*(x1*y1 - x2*y2) + c*(y1*y1 - y2*y2)) line0 = Line(a0, b0, c0, self.geometry) if self.line.null(): raise ValueError, \ "The line between %s and %s is null," \ "so the midpoint is not defined" % \ (str(self.point1), str(self.point2)) return line0 @check_geometry def quadrance(self): """ Calculate the quadrance between the two points of the line segment. """ return (self.point1 - self.point2).norm() @check_geometry def quadrola(self, K): x1, y1 = self.point1.form() x2, y2 = self.point2.form() a, b, c = self.geometry.form X02 = self.point1.norm() X12 = self.point2.norm() aa, bb, cc = M(a*(x2 - x1) + b*(y2 - y1), b*(x2 - x1) + c*(y2 - y1)) return Conic(4*(aa - K*a), 4*2*(bb - K*b), 4*(cc - K*c), 4*(X02 - X12)*(a*(x2 - x1) + b*(y2 - y1)) + \ 4*K*(a*(x1 + x2) + b*(y1 + y2)), 4*(X02 - X12)*(b*(x2 - x1) + c*(y2 - y1)) + \ 4*K*(b*(x1 + x2) + c*(y1 + y2)), (K - X02 - X12)*(K - X02 - X12) - 4*X02*X12, self.geometry)
def random_line(field, geometry): a, b, c = field.random(), field.random(), field.random() return Line(a, b, c, geometry)