Exemple #1
0
 def Snap(self, p):
     try:
         r, phi = self.trafo.inverse()(p).polar()
         start_angle = self.start_angle; end_angle = self.end_angle
         p2 = self.trafo(Polar(1, phi))
         if start_angle == end_angle:
             result = (abs(p - p2), p2)
         else:
             result = []
             if phi < 0:
                 phi = phi + 2 * pi
             if start_angle < end_angle:
                 between = start_angle <= phi <= end_angle
             else:
                 between = start_angle <= phi or phi <= end_angle
             if between:
                 result.append((abs(p - p2), p2))
             start = self.trafo(Polar(self.start_angle))
             end = self.trafo(Polar(self.end_angle))
             if self.arc_type == ArcArc:
                 result.append((abs(start - p), start))
                 result.append((abs(end - p), end))
             elif self.arc_type == ArcChord:
                 result.append((snap_to_line(start, end, p)))
             elif self.arc_type == ArcPieSlice:
                 center = self.trafo.offset()
                 result.append(snap_to_line(start, center, p))
                 result.append(snap_to_line(end, center, p))
             result = min(result)
         return result
     except SingularMatrix:
         # XXX this case could be handled better.
         return (1e200, p)
def create_star_path(corners, outer_radius, inner_radius):
    outer_radius = unit.convert(outer_radius)
    inner_radius = unit.convert(inner_radius)
    path = CreatePath()
    angle = math.pi * 2 / corners
    for i in range(corners):
        path.AppendLine(Polar(outer_radius, angle * i))
        path.AppendLine(Polar(inner_radius, angle * i + angle / 2))
    path.AppendLine(path.Node(0))
    path.ClosePath()
    return path
Exemple #3
0
 def gradient_geometry(self, flag, name, xorig, yorig, angle, length, a, b,
                       c, d, tx, ty):
     trafo = Trafo(a, b, c, d, tx, ty)
     trafo = artboard_trafo_inv(trafo(artboard_trafo))
     start = Point(xorig, yorig)
     end = start + Polar(length, (pi * angle) / 180.0)
     self.gradient_geo = (name, trafo, start, end)
Exemple #4
0
 def apply_constraint(self, p, state):
     if state & const.ConstraintMask:
         r, phi = (p - self.start).polar()
         pi12 = pi / 12
         phi = pi12 * floor(phi / pi12 + 0.5)
         p = self.start + Polar(r, phi)
     return p
Exemple #5
0
    def recompute(self):
        h1, h2, h3, theta, p1, p2 = self.h1, self.h2, self.h3, self.theta, \
                                    self.p1, self.p2
        xvect = (p2 - p1).normalized()
        angle = (p2 - p1).polar()[1] + theta * pi / 180
        yvect = Polar(1, angle)

        new = Sketch.CreatePath()
        newpaths = [new]

        new.AppendLine(p1)
        new.AppendLine(p1 + h1 * yvect)
        new = Sketch.CreatePath()
        newpaths.append(new)
        new.AppendLine(p1 + h3 * yvect)
        new.AppendLine(p2 + h3 * yvect)
        new = Sketch.CreatePath()
        newpaths.append(new)
        new.AppendLine(p2)
        new.AppendLine(p2 + h2 * yvect)

        for new in newpaths:
            new.Transform(self.trafo)
        if self.objects:
            self.objects[0].SetPaths(newpaths)
        else:
            lines = Sketch.PolyBezier(tuple(newpaths))
            self.set_objects([lines])
Exemple #6
0
 def apply_constraint(self, p, state):
     if state & const.ConstraintMask:
         if self.selection in self.selAspect:
             ref_x, ref_y = self.reference
             aspect = self.aspect
             if aspect is None:
                 # width is 0
                 p = Point(self.drag_start.x, p.y)
             else:
                 w = p.x - ref_x
                 h = p.y - ref_y
                 if w == 0:
                     w = 0.00001
                 a = h / w
                 if a > 0:
                     sign = 1
                 else:
                     sign = -1
                 if abs(a) > aspect:
                     h = sign * w * aspect
                 else:
                     w = sign * h / aspect
                 p = Point(ref_x + w, ref_y + h)
         elif self.selection == -1:
             pi4 = math.pi / 4
             off = p - self.drag_start
             d = Polar(pi4 * round(math.atan2(off.y, off.x) / pi4))
             p = self.drag_start + (off * d) * d
     return p
Exemple #7
0
 def GetHandles(self):
     handles = []
     r1 = self.r1
     r2 = self.r2
     theta1 = self.theta1
     theta2 = self.theta2
     p1 = Polar(r1, theta1*pi/180)
     p2 = Polar(r2, theta1*pi/180)
     p3 = Polar(r1, theta2*pi/180)
     p4 = Polar(r2, theta2*pi/180)
     p5 = 0.5*(p1+p2)
     p6 = 0.5*(p3+p4)
     
     for p in (p1, p2, p3, p4, p5, p6):
         handles.append(handle.MakeControlHandle(self.trafo(p)))        
     return handles
Exemple #8
0
    def GetHandles(self):
        handles = []
        theta1 = self.theta1
        theta2 = self.theta2
        if theta2 < theta1:
            theta2 = theta2 + 360
        p1 = Polar(self.l1, theta1 * pi / 180)
        p2 = Polar(self.l2, theta2 * pi / 180)
        p3 = Rotation(pi / 360 * (theta2 - theta1))(Polar(
            self.r, theta1 * pi / 180))

        for p in (p1, p2):
            handles.append(handle.MakeNodeHandle(self.trafo(p)))

        for p in (0.5 * p1, 0.5 * p2, p3):
            handles.append(handle.MakeControlHandle(self.trafo(p)))

        return handles
Exemple #9
0
 def GetSnapPoints(self):
     t = self.trafo
     start_angle = self.start_angle; end_angle = self.end_angle
     if self.start_angle == self.end_angle:
         a = Point(t.m11, t.m21)
         b = Point(t.m12, t.m22)
         c = t.offset()
         return [c, c + a, c - a, c + b, c - b]
     else:
         points = [t(Polar(start_angle)), t(Polar(end_angle)), t.offset()]
         if end_angle < start_angle:
             end_angle = end_angle + 2 * pi
         pi2 = pi / 2
         angle = pi2 * (floor(start_angle / pi2) + 1)
         while angle < end_angle:
             points.append(t(Polar(1, angle)))
             angle = angle + pi2
         return points
Exemple #10
0
    def Snap(self, p):
        try:
            x, y = self.trafo.inverse()(p)
            minx = self.radius1
            maxx = 1 - self.radius1
            miny = self.radius2
            maxy = 1 - self.radius2
            if minx < x < maxx:
                if miny < y < maxy:
                    ratio = hypot(self.trafo.m11, self.trafo.m21) \
                          / hypot(self.trafo.m12, self.trafo.m22)
                    if x < 0.5:
                        dx = x
                    else:
                        dx = 1 - x
                    if y < 0.5:
                        dy = y
                    else:
                        dy = 1 - y
                    if dy / dx > ratio:
                        x = round(x)
                    else:
                        y = round(y)
                elif y > maxy:
                    y = 1
                else:
                    y = 0
            elif miny < y < maxy:
                if x > maxx:
                    x = 1
                else:
                    x = 0
            elif minx > 0 and miny > 0:
                # the round corners
                if x < 0.5:
                    cx = minx
                else:
                    cx = maxx
                if y < 0.5:
                    cy = miny
                else:
                    cy = maxy
                trafo = Trafo(minx, 0, 0, miny, cx, cy)
                r, phi = trafo.inverse()(x, y).polar()
                x, y = trafo(Polar(1, phi))
            else:
                # normal corners
                x = round(min(max(x, 0), 1))
                y = round(min(max(y, 0), 1))

            p2 = self.trafo(x, y)
            return (abs(p - p2), p2)
        except SingularMatrix:
            return (1e200, p)
Exemple #11
0
 def Ellipse(self, ell):
     trf = ell.trafo
     if (trf.m12 == 0 and trf.m21 == 0) or (trf.m11 == 0 and trf.m22 == 0):
         self.FillStyle(ell.Properties())
         left, top, right, bottom = self.rect_to_ltrb(ell, Point(-1, -1))
         if ell.start_angle == ell.end_angle:
             self.packrec('<LHhhhh', 7, 0x0418, bottom, right, top, left)
         else:
             xe, ye = map(rndtoint,
                          self.trafo(ell.trafo(Polar(1, ell.start_angle))))
             xs, ys = map(rndtoint,
                          self.trafo(ell.trafo(Polar(1, ell.end_angle))))
             if ell.arc_type == const.ArcArc:
                 function = 0x0817
             elif ell.arc_type == const.ArcPieSlice:
                 function = 0x081A
             elif ell.arc_type == const.ArcChord:
                 function = 0x0830
             self.packrec('<LHhhhhhhhh', 11, function, ye, xe, ys, xs,
                          bottom, right, top, left)
     else:
         self.PolyBezier(ell.Paths(), ell.Properties())
Exemple #12
0
    def recompute(self):
        r1 = self.r1
        r2 = self.r2
        theta1 = self.theta1
        theta2 = self.theta2
        if theta2 < theta1:
            theta2 = theta2+360

        ring2 = Sketch.Ellipse(start_angle=theta1*pi/180,
                               end_angle=theta2*pi/180,
                               arc_type=0).Paths()[0]
        ring1 = ring2.Duplicate()
        ring2.Transform(Scale(r2))
        ring1.Transform(Scale(r1))
        new = Sketch.CreatePath()
        newpaths = [new]

        new.AppendLine(Polar(r1, theta1*pi/180.))
        for i in range(ring2.len):
            segment = ring2.Segment(i)
            new.AppendSegment(*segment)

        new.AppendLine(Polar(r2, theta2*pi/180.))
        new.AppendLine(Polar(r1, theta2*pi/180.))

        ring1.Transform(Scale(-1,1))
        ring1.Transform(Rotation((180+theta1+theta2)*pi/180.))
        
        for i in range(ring1.len):
            s = ring1.Segment(i)
            new.AppendSegment(*s)

        for path in newpaths:
            path.Transform(self.trafo)
        if self.objects:
            self.objects[0].SetPaths(newpaths)
        else:
            obj = Sketch.PolyBezier(tuple(newpaths))
            self.set_objects([obj])
Exemple #13
0
 def update_rects(self):
     trafo = self.trafo
     start = trafo.offset()
     # On some systems, atan2 can raise a ValueError if both
     # parameters are 0. In that case, the actual value the of angle
     # is not important since in the computation of p below, the
     # coordinate depending on the angle will always be 0 because
     # both trafo coefficients are 0. So set the angle to 0 in case
     # of an exception.
     try:
         phi1 = atan2(trafo.m12, trafo.m11)
     except ValueError:
         phi1 = 0
     try:
         phi2 = atan2(trafo.m22, trafo.m21)
     except ValueError:
         phi2 = 0
     p = Point(trafo.m11 * cos(phi1) + trafo.m12 * sin(phi1),
               trafo.m21 * cos(phi2) + trafo.m22 * sin(phi2))
     self.coord_rect = r = Rect(start + p, start - p)
     if self.properties.HasLine():
         width = self.properties.line_width
         r = r.grown(width / 2 + 1)
         # add the bounding boxes of arrows
         if self.arc_type == ArcArc:
             pi2 = pi / 2
             arrow1 = self.properties.line_arrow1
             if arrow1 is not None:
                 pos = trafo(Polar(1, self.start_angle))
                 dir = trafo.DTransform(Polar(1, self.start_angle - pi2))
                 r = UnionRects(r, arrow1.BoundingRect(pos, dir, width))
             arrow2 = self.properties.line_arrow2
             if arrow2 is not None:
                 pos = trafo(Polar(1, self.end_angle))
                 dir = trafo.DTransform(Polar(1, self.end_angle + pi2))
                 r = UnionRects(r, arrow2.BoundingRect(pos, dir, width))
     self.bounding_rect = r
Exemple #14
0
    def DragHandle(self, pa, pb, selection):
        try:
            inverse = self.trafo.inverse()
        except SingularMatrix:
            return

        pa, pb = map(inverse, (pa, pb))
        delta = pb - pa

        theta1 = self.theta1
        theta2 = self.theta2
        if theta2 < theta1:
            theta2 = theta2 + 360

        p1 = Polar(self.l1, theta1 * pi / 180)
        p2 = Polar(self.l2, theta2 * pi / 180)
        p3 = Rotation(pi / 360 * (theta2 - theta1))(Polar(
            self.r, theta1 * pi / 180))

        if selection == 1:
            p1 = p1 + delta
            self.l1, angle = p1.polar()
            if not self.shift_pressed:
                self.theta1 = angle * 180 / pi
        elif selection == 2:
            p2 = p2 + delta
            self.l2, angle = p2.polar()
            if not self.shift_pressed:
                self.theta2 = angle * 180 / pi
        elif selection == 3:
            self.theta1 = (0.5 * p1 + delta).polar()[1] * 180 / pi
        elif selection == 4:
            self.theta2 = (0.5 * p2 + delta).polar()[1] * 180 / pi
        elif selection == 5:
            p3 = p3 + delta
            l, angle = p3.polar()
            angle = angle * 180 / pi % 360
            begin = self.theta1 % 360
            end = self.theta2 % 360
            if end < begin:
                end = end + 360
            if angle >= begin and angle <= end:
                self.r = l
            else:
                self.r = 0
        if self.control_pressed:
            if selection in (1, 3):
                self.theta1 = int(0.5 + self.theta1 / 5.) * 5
            elif selection in (2, 4):
                self.theta2 = int(0.5 + self.theta2 / 5.) * 5

        self.recompute()
Exemple #15
0
 def recompute(self):
     path = CreatePath()
     vertices = self.vertices
     radius = self.radius
     twopi = 2 * pi
     halfpi = pi / 2
     for i in range(vertices + 1):
         path.AppendLine(Polar(radius, (twopi * i) / vertices + halfpi),
                         ContAngle)
     path.ClosePath()
     path.Transform(self.trafo)
     if self.objects:
         self.objects[0].SetPaths((path,))
     else:
         self.set_objects([PolyBezier((path,))])
Exemple #16
0
    def DragHandle(self, pa, pb, selection):
        try:
            inverse = self.trafo.inverse()
        except SingulareMatrix:
            return
        pa, pb = map(inverse, (pa, pb))
        delta = pb - pa

        p1, p2, p3 = self.p1, self.p2, self.p3
        if self.control_pressed:
            c = self.Calc()[0]
            l1 = (p1 - c).polar()[0]
            l2 = (p2 - c).polar()[0]
            l3 = (p3 - c).polar()[0]

        if selection == 1 or self.shift_pressed:
            p1 = p1 + delta
            if self.control_pressed:
                angle = (p1 - c).polar()[1]
                p1 = Polar(l1, angle) + c
            self.p1 = p1
        if selection == 2 or self.shift_pressed:
            p2 = p2 + delta
            if self.control_pressed:
                angle = (p2 - c).polar()[1]
                p2 = Polar(l2, angle) + c
            self.p2 = p2

        if selection == 3 or self.shift_pressed:
            p3 = p3 + delta
            if self.control_pressed:
                angle = (p3 - c).polar()[1]
                p3 = Polar(l3, angle) + c
            self.p3 = p3

        self.recompute()
Exemple #17
0
    def GetHandles(self):
        h1, h2, h3, theta, p1, p2 = self.h1, self.h2, self.h3, self.theta, \
                                    self.p1, self.p2
        xvect = (p2 - p1).normalized()
        angle = (p2 - p1).polar()[1] + theta * pi / 180
        yvect = Polar(1, angle)

        handles = []
        for p in (p1, p2):
            handles.append(MakeRoundHandle(self.trafo(p)))

        for p in (p1 + h1 * yvect, p2 + h2 * yvect,
                  0.5 * (p1 + p2) + h3 * yvect, p1 + h1 * yvect * 0.5,
                  p2 + h2 * yvect * 0.5):
            handles.append(MakeControlHandle(self.trafo(p)))
        return handles
Exemple #18
0
def create_spiral_path(rotation, radius):
    r = unit.convert(radius)
    rate = r / (rotation * 2 * pi)

    def tangent(phi, a=0.55197 * rate):
        return a * Point(cos(phi) - phi * sin(phi), sin(phi) + phi * cos(phi))

    pi2 = pi / 2.0
    angle = 0
    tang = tangent(0)
    path = CreatePath()
    p = Point(0, 0)
    path.AppendLine(p)
    for i in range(rotation * 4):
        p1 = p + tang
        angle = pi2 * (i + 1)
        p = Polar(rate * angle, angle)
        tang = tangent(angle)
        p2 = p - tang
        path.AppendBezier(p1, p2, p, ContSymmetrical)
    return path
Exemple #19
0
 def apply_constraint(self, p, state):
     if state & ConstraintMask:
         try:
             inverse = self.trafo.inverse()
             p2 = inverse(p)
             r, phi = p2.polar()
             pi12 = pi / 12
             angle = pi12 * floor(phi / pi12 + 0.5)
             pi2 = 2 * pi
             d1 = fmod(abs(phi - angle), pi2)
             if self.selection == 1:
                 selected_angle = self.end_angle
             else:
                 selected_angle = self.start_angle
             d2 = fmod(abs(phi - selected_angle), pi2)
             if d2 < d1:
                 phi = selected_angle
             else:
                 phi = angle
             p = self.trafo(Polar(r, phi))
         except SingularMatrix:
             pass
     return p
Exemple #20
0
    def recompute(self):
        p1 = Polar(self.l1, self.theta1 * pi / 180)
        p2 = Polar(self.l2, self.theta2 * pi / 180)

        new = Sketch.CreatePath()
        newpaths = [new]

        new.AppendLine(p1)
        new.AppendLine((0, 0))
        new.AppendLine(p2)

        new.Transform(self.trafo)
        alpha = p1.polar()[1]
        beta = p2.polar()[1]
        if self.objects:
            self.objects[0].SetPaths(newpaths)
            self.objects[1].SetAngles(alpha, beta)
            trafo = self.trafo(Scale(self.r, self.r))
            self.objects[1].set_transformation(trafo)
        else:
            lines = Sketch.PolyBezier(tuple(newpaths))
            circle = Sketch.Ellipse(start_angle=alpha, end_angle=beta)
            circle.Transform(Scale(self.r, self.r))
            self.set_objects([lines, circle])
Exemple #21
0
    def DragHandle(self, pa, pb, selection):
        try:
            inverse = self.trafo.inverse()
        except SingularMatrix:
            return

        pa, pb = map(inverse, (pa, pb))
        delta = pb - pa

        h1, h2, h3, theta, p1, p2 = self.h1, self.h2, self.h3, self.theta, \
                                    self.p1, self.p2
        xvect = (p2 - p1).normalized()
        xnvect = Point(xvect.y, -xvect.x)
        angle = (p2 - p1).polar()[1] + theta * pi / 180
        yvect = Polar(1, angle)
        sin_theta = xnvect * yvect
        if sin_theta == 0:
            h = delta * xvect
        else:
            h = (xnvect * delta) / sin_theta
        l, angle = (p1 - p2).polar()

        if selection == 1:
            p1 = p1 + delta
            if self.shift_pressed:
                s, angle = (p1 - p2).polar()
                p1 = (p1 - p2) * l / s + p2
            if self.control_pressed:
                s, angle = (p1 - p2).polar()
                theta = int(theta * 180 / pi / 15 + 0.5) * pi / 180 * 15.
                p1 = p2 + s * Polar(1, angle)
            self.p1 = p1
        elif selection == 2:
            l, angle = (p1 - p2).polar()
            p2 = p2 + delta
            if self.shift_pressed:
                s, angle = (p2 - p1).polar()
                p2 = (p2 - p1) * l / s + p1
            if self.control_pressed:
                s, angle = (p2 - p1).polar()
                theta = int(theta * 180 / 15 / pi + 0.5) * pi / 180 * 15.
                p2 = p1 + s * Polar(1, theta)
            self.p2 = p2
        elif selection == 3:
            self.h1 = h1 + h
        elif selection == 4:
            self.h2 = h2 + h
        elif selection == 5:
            # the middle line
            h3 = max(0, h3 + h)
            if h3 > h1: h3 = h1
            if h3 > h2: h3 = h2
            self.h3 = h3

        elif selection == 6:
            g = p1 + h1 * yvect * 0.5
            p = g + delta
            angle = (p - p1).polar()[1] - (p2 - p1).polar()[1]
            self.theta = 180 * angle / pi
        elif selection == 7:
            g = p2 + h2 * yvect * 0.5
            p = g + delta
            angle = (p - p2).polar()[1] - (p2 - p1).polar()[1]
            self.theta = 180 * angle / pi

        self.recompute()
Exemple #22
0
    def DragHandle(self, pa, pb, selection):
        try:
            inverse = self.trafo.inverse()
        except SingularMatrix:
            return
        
        pa, pb = map(inverse, (pa, pb))
        delta = pb-pa

        r1 = self.r1
        r2 = self.r2
        theta1 = self.theta1 % 360
        theta2 = self.theta2 % 360
        p1 = Polar(r1, theta1*pi/180)
        p2 = Polar(r2, theta1*pi/180)
        p3 = Polar(r1, theta2*pi/180)
        p4 = Polar(r2, theta2*pi/180)
        p5 = 0.5*(p1+p2)
        p6 = 0.5*(p3+p4)

        if theta2 < theta1:
            theta2 = theta2+360
            
        if selection == 1:
            p1 = p1 + delta
            self.r1, angle = p1.polar()
            angle = angle*180/pi % 360
            if angle < theta1-2 or angle > theta2+2:
                self.r1 = 0
            if not self.shift_pressed:
                self.theta1 = angle
            
        elif selection == 2:
            p2 = p2 + delta
            self.r2, angle = p2.polar()
            if not self.shift_pressed:                
                self.theta1 = angle*180/pi
        elif selection == 3:
            p3 = p3 + delta
            self.r1, angle = p3.polar()
            angle = angle*180/pi % 360    
            if angle < theta1-2 or angle > theta2+2:
                self.r1 = 0
            if not self.shift_pressed:
                self.theta2 = angle
        elif selection == 4:
            p4 = p4 + delta
            self.r2, angle = p4.polar()
            if not self.shift_pressed:                
                self.theta2 = angle*180/pi
        elif selection == 5:
            p5 = p5 + delta
            angle = p5.polar()[1]            
            self.theta1 = angle*180/pi    
        elif selection == 6:
            p6 = p6 + delta
            angle = p6.polar()[1]
            self.theta2 = angle*180/pi

        if self.control_pressed:
            if selection in (1,2,5):
                self.theta1 = int(0.5+self.theta1/5.)*5
            elif selection in (3,4,6):
                self.theta2 = int(0.5+self.theta2/5.)*5


        self.recompute()