Beispiel #1
0
def create_ship(x, y, **kwargs):
    return Entity(
        x,
        y,
        shape=Polygon.from_pointlist([
            Vector(+0, +8),
            Vector(-5, -8),
            Vector(+5, -8),
        ]),
        color=Color(50, 100, 200),
        **kwargs,
    )
Beispiel #2
0
def create_asteroid(x, y, **kwargs):
    bright = randint(20, 50)
    return Entity(
        x,
        y,
        shape=Polygon.from_pointlist([
            Vector(+0, -6),
            Vector(-5, +6),
            Vector(+5, +6),
        ]),
        color=Color(1 * bright, 3 * bright, 2 * bright),
        **kwargs,
    )
Beispiel #3
0
    def get_centerpoint(self):
        """Get the center of mass for the polygon"""

        xes = [p.x for p in self.points]
        yes = [p.y for p in self.points]

        return Vector(float(sum(xes)) / len(xes), float(sum(yes)) / len(yes))
Beispiel #4
0
def intersect_lineseg_lineseg(p1, p2, q1, q2):
    """Intersect two line segments

	@type p1: Vector
	@param p1: The first point on the first line segment

	@type p2: Vector
	@param p2: The second point on the first line segment

	@type q1: Vector
	@param q1: The first point on the secondline segment

	@type q2: Vector
	@param q2: The second point on the second line segment
	"""

    if max(q1.x, q2.x) < min(p1.x, p2.x): return None
    if min(q1.x, q2.x) > max(p1.x, p2.x): return None
    if max(q1.y, q2.y) < min(p1.y, p2.y): return None
    if min(q1.y, q2.y) > max(p1.y, p2.y): return None

    ll = __intersect_line_line_u(p1, p2, q1, q2)

    if ll == None: return None
    if ll[0] < 0 or ll[0] > 1: return None
    if ll[1] < 0 or ll[1] > 1: return None

    return Vector(p1.x + ll[0] * (p2.x - p1.x), p1.y + ll[0] * (p2.y - p1.y))
Beispiel #5
0
def intersect_lineseg_ray(p1, p2, q1, q2):
    """Intersect a line segment and a ray

	@type p1: Vector
	@param p1: The starting point of the line segment

	@type p2: Vector
	@param p2: The ending point of the line segment

	@type q1: Vector
	@param q1: The first point on the ray

	@type q2: Vector
	@param q2: The second point on the ray

	@return: The point of intersection or None
	"""

    ll = __intersect_line_line_u(p1, p2, q1, q2)

    if ll == None: return None
    if ll[0] < 0 or ll[0] > 1: return None
    if ll[1] < 0: return None

    return Vector(p1.x + ll[0] * (p2.x - p1.x), p1.y + ll[0] * (p2.y - p1.y))
Beispiel #6
0
    def __mul__(self, val):

        if isinstance(val, Vector):

            x = val.x * self.data[0][0] + val.y * self.data[0][1] + self.data[
                0][2]
            y = val.x * self.data[1][0] + val.y * self.data[1][1] + self.data[
                1][2]

            return Vector(x, y)

        elif isinstance(val, Transform):
            data = [[0 for y in range(3)] for x in range(3)]
            for i in range(3):
                for j in range(3):
                    for k in range(3):
                        data[i][j] += self.data[i][k] * val.data[k][j]

            return Transform(data)

        elif isinstance(val, Polygon):
            p_transform = [self * v for v in val.points]
            return Polygon.from_pointlist(p_transform)

        else:
            raise ValueError("Unknown multiplier: %s" % val)
Beispiel #7
0
    def from_tuples(tuples):
        """Create a polygon from 2-tuples

		@type tuples: List
		@param tuples: List of tuples of x,y coordinates
		"""

        p = Polygon()
        p.points = [Vector(t[0], t[1]) for t in tuples]
        return p
Beispiel #8
0
        def find_point_in_poly(pts):
            # find point inside of pts according to http://www.exaflop.org/docs/cgafaq/cga2.html#Subject%202.06:%20How%20do%20I%20find%20a%20single%20point%20inside%20a%20simple%20polygonu
            # alternative approaches at http://stackoverflow.com/questions/9797448/get-a-point-inside-the-polygon, http://www.dummies.com/how-to/content/how-to-pinpoint-the-center-of-a-triangle.html

            def threeways(iterable):
                import itertools
                args = [iter(iterable)] * 3
                return itertools.izip_longest(fillvalue=None, *args)

            for a, b, c in threeways(pts):
                avgx = sum([each.x for each in (a, b, c)]) / 3.0
                avgy = sum([each.y for each in (a, b, c)]) / 3.0
                triangle_center = Vector(avgx, avgy)
                if Polygon.contains_point_s([a, b, c], triangle_center):
                    print "triangle", (a, b, c), triangle_center
                    return triangle_center
Beispiel #9
0
	def regular(center, radius, points):
		"""Create a regular polygon

		@type center: Vector
		@param center: The center point of the polygon

		@type radius: float
		@param radius: The radius of the polygon

		@type points: int
		@param points: The number of polygon points. 3 will create a triangle, 4 a square, and so on.
		"""

		angular_increment = 2 * math.pi / points

		p = Polygon()
		for i in range(points):
			p.add_point( Vector(center.x + radius * math.cos(i * angular_increment), center.y + radius * math.sin(i * angular_increment)) )

		return p
Beispiel #10
0
def intersect_line_line(p1, p2, q1, q2):
    """Intersect two lines

	@type p1: Vector
	@param p1: The first point of the first line

	@type p2: Vector
	@param p2: The second point of the first line

	@type q1: Vector
	@param q1: The first point of the second line

	@type q2: Vector
	@param q2: The second point of the second line

	@return: The point of intersection or None
	"""

    ll = __intersect_line_line_u(p1, p2, q1, q2)

    if ll == None: return None
    return Vector(p1.x + ll[0] * (p2.x - p1.x), p1.y + ll[0] * (p2.y - p1.y))
Beispiel #11
0
	def contains_point_s(pts, p) :
		"""Checks if the polygon defined by the point list pts contains the point p"""

		# see if we find a line segment that p is on
		for a,b in list(zip(pts[0:], pts[1:])) + [(pts[-1], pts[0])]:
			d = distance_point_lineseg_squared(p, a, b)
			if d < EPSILON * EPSILON: return 2

		# p is not on the boundary, cast ray and intersect to see if we are inside
		intersections = set(intersect_poly_ray(pts, p, p + Vector(1,0)))

		# filter intersection points that are boundary points
		for int_point in filter(lambda x: x in pts, intersections):

			i = pts.index(int_point)
			prv = pts[i-1]
			nxt = pts[(i+1) % len(pts)]

			if point_orientation(p, int_point, nxt) == point_orientation(p,int_point, prv):
				intersections.remove(int_point)

		# we are inside if we have an odd amount of polygon intersections
		return 1 if len(intersections) % 2 == 1 else 0
Beispiel #12
0
 def parse_vec(s):
     x, y = s.split(",")
     return Vector(float(x), float(y))
Beispiel #13
0
    def convert_element(e, transform):
        """Convert an SVG path element to one or multiple Py2D polygons."""

        # get data from the <path> element
        id = e.get("id")
        d = e.get("d")

        #print "CONVERTING %s: %s" % (id, d)

        def parse_commands(draw_commands):
            """Generator Function to parse a SVG draw command sequence into command and parameter tuples"""
            tokens = draw_commands.split(" ")
            while tokens:
                # find the next token that is a command
                par_index = next(i for i, v in enumerate(tokens[1:] + ["E"])
                                 if re.match('^[a-zA-Z]$', v)) + 1

                # first token should always be the command, rest the parameters
                cmd = tokens[0]
                pars = tokens[1:par_index]

                # remove the parsed tokens
                del tokens[:par_index]

                yield cmd, pars

        def parse_vec(s):
            x, y = s.split(",")
            return Vector(float(x), float(y))

        polys = []
        verts = []
        relative_pos = Vector(0.0, 0.0)
        last_control = None
        for cmd, pars in parse_commands(d):

            #print "cmd: %s, pars: %s" % (cmd, pars)

            if cmd == "m" or cmd == "l":
                for p in pars:
                    relative_pos += parse_vec(p)
                    verts.append(relative_pos)

            elif cmd == "M" or cmd == "L":
                for p in pars:
                    relative_pos = parse_vec(p)
                    verts.append(relative_pos)

            elif cmd == "c" or cmd == "C":
                # create cubic polybezier

                for i in range(0, len(pars), 3):
                    c1, c2, b = parse_vec(pars[i]), parse_vec(
                        pars[i + 1]), parse_vec(pars[i + 2])

                    if cmd == "c":
                        # convert to relative
                        c1 += relative_pos
                        c2 += relative_pos
                        b += relative_pos

                    bez = flatten_cubic_bezier(relative_pos, b, c1, c2,
                                               bezier_max_divisions,
                                               bezier_max_flatness)

                    last_control = c2
                    relative_pos = b

                    verts.extend(bez)

            elif cmd == "s" or cmd == "S":
                # shorthand / smooth cubic polybezier

                for i in range(0, len(pars), 2):
                    c2, b = parse_vec(pars[i]), parse_vec(pars[i + 1])
                    c1 = relative_pos + (relative_pos - last_control)

                    if cmd == "s":
                        # convert to relative
                        c2 += relative_pos
                        b += relative_pos

                    bez = flatten_cubic_bezier(relative_pos, b, c1, c2,
                                               bezier_max_divisions,
                                               bezier_max_flatness)

                    last_control = c2
                    relative_pos = b

                    verts.extend(bez)

            elif cmd == "z":
                # close line by only moving relative_pos to first vertex

                polys.append(transform * Polygon.from_pointlist(verts))
                relative_pos = verts[0]
                verts = []

            else:
                warnings.warn(
                    "Unrecognized SVG path command: %s - path skipped" % cmd)
                polys = []
                break

        if verts:
            polys.append(transform * Polygon.from_pointlist(verts))
        #print "----"

        return id, polys
Beispiel #14
0
def get_triangle():
    return Polygon.from_pointlist([
        Vector(1.1, 2.2),
        Vector(3.3, 4.4),
        Vector(5.5, 6.6),
    ])