def vertices(self, current, previous): ox, oy = self.origin(current) x2,y2 = self._args x0, y0 = current x1,y1 = 2*x0 - previous[0], 2*y0 - previous[1] x2, y2 = x2+ox, y2+oy self.previous = x1,y1 vertices = geometry.quadratic( (x0,y0), (x1,y1), (x2,y2) ) return vertices[1:]
def vertices(self, current, last_control_point=None): ox, oy = self.origin(current) x1,y1,x2,y2 = self._args x0,y0 = current x1,y1 = x1+ox, y1+oy x2,y2 = x2+ox, y2+oy self.previous = x1,y1 vertices = geometry.quadratic((x0,y0), (x1,y1), (x2,y2)) return vertices[1:]
def vertices(self, current, previous): ox, oy = self.origin(current) x2, y2 = self._args x0, y0 = current x1, y1 = 2 * x0 - previous[0], 2 * y0 - previous[1] x2, y2 = x2 + ox, y2 + oy self.previous = x1, y1 vertices = geometry.quadratic((x0, y0), (x1, y1), (x2, y2)) return vertices[1:]
def vertices(self, current, last_control_point=None): ox, oy = self.origin(current) x1, y1, x2, y2 = self._args x0, y0 = current x1, y1 = x1 + ox, y1 + oy x2, y2 = x2 + ox, y2 + oy self.previous = x1, y1 vertices = geometry.quadratic((x0, y0), (x1, y1), (x2, y2)) return vertices[1:]
def __init__(self, a=1.0, b=1.0, c=0.0, d=0.0, e=0.0, f=-1.0, color=None): Shape.__init__(self, color) if c*c - 4*a*b >= 0: raise Exception("Not an ellipse") self.a = a self.b = b self.c = c self.d = d self.e = e self.f = f self.gradient = Transform(2*a, c, d, c, 2*b, e) self.center = self.gradient.inverse() * Vector(0, 0) y1, y2 = quadratic(b-c*c/4*a, e-c*d/2*a, f-d*d/4*a) x1, x2 = quadratic(a-c*c/4*b, d-c*e/2*b, f-e*e/4*b) self.bound = AABox.from_vectors(Vector(-(d + c*y1)/2*a, y1), Vector(-(d + c*y2)/2*a, y2), Vector(x1, -(e + c*x1)/2*b), Vector(x2, -(e + c*x2)/2*b)) if not self.contains(self.center): raise Exception("Internal error, center not inside ellipse")
def __init__(self, a=1.0, b=1.0, c=0.0, d=0.0, e=0.0, f=-1.0, color=None): Shape.__init__(self, color) if c * c - 4 * a * b >= 0: raise Exception("Not an ellipse") self.a = a self.b = b self.c = c self.d = d self.e = e self.f = f self.gradient = Transform(2 * a, c, d, c, 2 * b, e) self.center = self.gradient.inverse() * Vector(0, 0) y1, y2 = quadratic(b - c * c / 4 * a, e - c * d / 2 * a, f - d * d / 4 * a) x1, x2 = quadratic(a - c * c / 4 * b, d - c * e / 2 * b, f - e * e / 4 * b) self.bound = AABox.from_vectors(Vector(-(d + c * y1) / 2 * a, y1), Vector(-(d + c * y2) / 2 * a, y2), Vector(x1, -(e + c * x1) / 2 * b), Vector(x2, -(e + c * x2) / 2 * b)) if not self.contains(self.center): raise Exception("Internal error, center not inside ellipse")
def intersections(self, c, p): # returns the two intersections of the line through c and p # and the ellipse. Defining a line as a function of a single # parameter u, x(u) = c.x + u * (p.x - c.x), (and same for y) # this simply solves the quadratic equation f(x(u), y(u)) = 0 pc = p - c u2 = self.a * pc.x**2 + self.b * pc.y**2 + self.c * pc.x * pc.y u1 = 2*self.a*c.x*pc.x + 2*self.b*c.y*pc.y \ + self.c*c.y*pc.x + self.c*c.x*pc.y + self.d*pc.x \ + self.e*pc.y u0 = self.a*c.x**2 + self.b*c.y**2 + self.c*c.x*c.y \ + self.d*c.x + self.e*c.y + self.f try: sols = quadratic(u2, u1, u0) except ValueError: raise Exception("Internal error, solutions be real numbers") return c + pc * sols[0], c + pc * sols[1]
def __init__(self, a=1.0, b=1.0, c=0.0, d=0.0, e=0.0, f=-1.0, color=None): Shape.__init__(self, color) self.a = a self.b = b self.c = c self.d = d self.e = e self.f = f t = Transform(2 * a, c, 0, c, 2 * b, 0) self.center = t.inverse() * Vector(-d, -e) l1, l0 = quadratic(1, 2 * (-a - b), 4 * a * b - c * c) v = t.eigv() axes = [v[0] * ((l0 / 2) ** -0.5), v[1] * ((l1 / 2) ** -0.5)] self.bound = Vector.union(self.center - axes[0] - axes[1], self.center - axes[0] + axes[1], self.center + axes[0] - axes[1], self.center + axes[0] + axes[1])
def intersections(self, c, p): # returns the two intersections of the line through c and p # and the ellipse. Defining a line as a function of a single # parameter u, x(u) = c.x + u * (p.x - c.x), (and same for y) # this simply solves the quadratic equation f(x(u), y(u)) = 0 pc = p - c u2 = self.a*pc.x**2 + self.b*pc.y**2 + self.c*pc.x*pc.y u1 = 2*self.a*c.x*pc.x + 2*self.b*c.y*pc.y \ + self.c*c.y*pc.x + self.c*c.x*pc.y + self.d*pc.x \ + self.e*pc.y u0 = self.a*c.x**2 + self.b*c.y**2 + self.c*c.x*c.y \ + self.d*c.x + self.e*c.y + self.f try: sols = quadratic(u2, u1, u0) except ValueError: raise Exception("Internal error, solutions be real numbers") return c+pc*sols[0], c+pc*sols[1]
def signed_distance_bound(self, p): def sgn(x): return 0 if x == 0 else x / abs(x) v = -sgn(self.value(p)) c = self.center pc = p - c u2 = self.a*pc.x**2 + self.b*pc.y**2 + self.c*pc.x*pc.y u1 = 2*self.a*c.x*pc.x + 2*self.b*c.y*pc.y \ + self.c*c.y*pc.x + self.c*c.x*pc.y + self.d*pc.x \ + self.e*pc.y u0 = self.a*c.x**2 + self.b*c.y**2 + self.c*c.x*c.y \ + self.d*c.x + self.e*c.y + self.f sols = quadratic(u2, u1, u0) crossings = c+pc*sols[0], c+pc*sols[1] if (p - crossings[0]).length() < (p - crossings[1]).length(): surface_pt = crossings[0] else: surface_pt = crossings[1] d = Vector(2*self.a*surface_pt.x + self.c*surface_pt.y + self.d, 2*self.b*surface_pt.y + self.c*surface_pt.x + self.e) return v * abs(d.dot(p - surface_pt) / d.length())