Ejemplo n.º 1
0
    def star(cls, peak_count, radius1, radius2, center=(0, 0), angle=0):
        """Create a radial pointed star polygon with the specified number
        of peaks.

        :param peak_count: The number of peaks. The resulting polygon will
            have twice this number of vertices. Must be >= 2.
        :type peak_count: int
        :param radius1: The peak or valley vertex radius. A vertex
            is aligned on ``angle`` with this radius.
        :type radius1: float
        :param radius2: The alternating vertex radius.
        :type radius2: float
        :param center: The center point of the polygon. If omitted,
            the polygon will be centered on the origin.
        :type center: Vec2
        :param angle: The starting angle for the vertices, in degrees.
        :type angle: float
        """
        if peak_count < 2:
            raise ValueError(
                "star polygon must have a minimum of 2 peaks")
        cx, cy = center
        angle_step = 180.0 / peak_count
        verts = []
        for i in range(peak_count):
            x, y = cos_sin_deg(angle)
            verts.append((x * radius1 + cx, y * radius1 + cy))
            angle += angle_step
            x, y = cos_sin_deg(angle)
            verts.append((x * radius2 + cx, y * radius2 + cy))
            angle += angle_step
        is_simple = (radius1 > 0.0) == (radius2 > 0.0)
        poly = cls(verts, is_convex=(radius1 == radius2), 
            is_simple=is_simple or None)
        if is_simple:
            poly._centroid = polypaths_planar_override.Vec2(*center)
        poly._max_r = max_r = max(abs(radius1), abs(radius2))
        poly._max_r2 = max_r * max_r
        if (radius1 >= 0.0) == (radius2 >= 0.0):
            if not poly.is_convex:
                poly._min_r = min_r = min(abs(radius1), abs(radius2))
                poly._min_r2 = min_r * min_r
            else:
                poly._min_r = min_r = (
                    (poly[0] + poly[1]) * 0.5 - center).length
                poly._min_r2 = min_r * min_r
        if radius1 > 0.0 and radius2 > 0.0:
            poly._dupe_verts = False
        return poly
Ejemplo n.º 2
0
    def regular(cls, vertex_count, radius, center=(0, 0), angle=0):
        """Create a regular polygon with the specified number of vertices
        radius distance from the center point. Regular polygons are
        always convex.

        :param vertex_count: The number of vertices in the polygon.
            Must be >= 3.
        :type vertex_count: int
        :param radius: distance from vertices to center point.
        :type radius: float
        :param center: The center point of the polygon. If omitted,
            the polygon will be centered on the origin.
        :type center: Vec2
        :param angle: The starting angle for the vertices, in degrees.
        :type angle: float
        """
        cx, cy = center
        angle_step = 360.0 / vertex_count
        verts = []
        for i in range(vertex_count):
            x, y = cos_sin_deg(angle)
            verts.append((x * radius + cx, y * radius + cy))
            angle += angle_step
        poly = cls(verts, is_convex=True)
        poly._centroid = polypaths_planar_override.Vec2(*center)
        poly._max_r = radius
        poly._max_r2 = radius * radius
        poly._min_r = min_r = ((poly[0] + poly[1]) * 0.5 - center).length
        poly._min_r2 = min_r * min_r
        poly._dupe_verts = False
        return poly
Ejemplo n.º 3
0
    def rotated(self, angle):
        """Compute the vector rotated by an angle.

        :param angle: The angle to rotate by, in degrees.
        :type angle: float
        :rtype: Vec2
        """
        vx, vy = self
        ca, sa = cos_sin_deg(angle)
        return tuple.__new__(Vec2, (vx * ca - vy * sa, vx * sa + vy * ca))
Ejemplo n.º 4
0
    def polar(cls, angle, length=1.0):
        """Create a vector from polar coordinates.

        :param angle: Vector angle in degrees from the positive x-axis.
        :type angle: float
        :param length: The length of the vector.
        :type length: float
        :rtype: Vec2
        """
        x, y = cos_sin_deg(angle)
        vec = tuple.__new__(cls, (x * length, y * length))
        vec.__dict__['length'] = length * 1.0
        return vec
Ejemplo n.º 5
0
    def rotation(cls, angle, pivot=None):
        """Create a rotation transform at the specified angle,
        optionally about the specified pivot point.

        :param angle: Rotation angle in degrees
        :type angle: float
        :param pivot: Point to rotate about, if omitted the
            rotation is about the origin.
        :type pivot: :class:`~polypaths_planar_override.Vec2`
        :rtype: Affine
        """
        ca, sa = cos_sin_deg(angle)
        if pivot is None:
            return tuple.__new__(cls, 
                (ca, sa, 0.0,
                -sa, ca, 0.0,
                 0.0, 0.0, 1.0))
        else:
            px, py = pivot
            return tuple.__new__(cls,
                (ca, sa, px - px*ca + py*sa,
                -sa, ca, py - px*sa - py*ca,
                 0.0, 0.0, 1.0))