-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate_shapes.py
executable file
·161 lines (137 loc) · 5.4 KB
/
create_shapes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/env python3
from pymunk import Poly, Body, Segment, Circle
from pymunk import moment_for_poly, moment_for_segment, moment_for_circle
def create_pentagon(p1=(0, 0), p2=(2, 0), p3=(3, 2), p4=(1, 4), p5=(-1, 2),
x=0, y=0, m=1, scalar=1, bt=Body.DYNAMIC):
'''
given points (p1..p5), mass (m), x-position (x), y-position (y),
scalar <to augment default points>, body_type (bt),
return (body, shape) tuple for a pentagon
'''
vertices = (p1, p2, p3, p4, p5)
vertices = tuple((v[0]*scalar, v[1]*scalar) for v in vertices)
shape = Poly(body=None, vertices=vertices) # will set body later
vertices = shape.get_vertices() # because Vec2d of vertices is needed
moment = moment_for_poly(mass=m, vertices=vertices)
body = Body(mass=m, moment=moment)
body.position = (x, y)
shape.body = body # set body here because init None above
return body, shape
def create_triangle(p1=(0, 0), p2=(1, 0), p3=(.5, .866), x=0, y=0,
m=1, scalar=1, bt=Body.DYNAMIC):
'''
given points (p1..p3), mass (m), x-position (x), y-position (y),
scalar <to augment default equilateral triangle>, body_type (bt),
The default values for p1,p2,p3 make an approx. equilateral triangle.
return (body, shape) tuple for a triangle
'''
vertices = (p1, p2, p3) # equilateral
vertices = tuple((v[0]*scalar, v[1]*scalar) for v in vertices)
shape = Poly(body=None, vertices=vertices) # will set body later
vertices = shape.get_vertices() # because Vec2d of vertices is needed
moment = moment_for_poly(mass=m, vertices=vertices)
body = Body(mass=m, moment=moment)
body.position = (x, y)
shape.body = body # set body here because init None above
return body, shape
def create_segment(p1=(0, 0), p2=(0, 1), thicc=1, x=0, y=0, m=1, scalar=1,
bt=Body.DYNAMIC):
'''
given point_1 (p1), point_2 (p2), thickness (thicc),
x-position (x), y-position (y), mass (m),
scalar <to augment the length>, body_type (bt)
return (body, shape) tuple for a line segment
'''
given_bt = bt
bt = Body.DYNAMIC if given_bt == 'dynamic' else Body.DYNAMIC
bt = Body.STATIC if given_bt == 'static' else Body.DYNAMIC
bt = Body.KINEMATIC if given_bt == 'kinematic' else Body.DYNAMIC
p2 = (p2[0]*scalar, p2[1]*scalar)
moment = moment_for_segment(mass=m, a=p1, b=p2, radius=thicc)
body = Body(mass=m, moment=moment, body_type=bt)
shape = Segment(body=body, a=p1, b=p2, radius=thicc)
body.position = (x, y)
return body, shape
def create_circle(r=1, x=0, y=0, m=1, bt=Body.DYNAMIC):
'''
given radius (r), x-position (x), y-position (y), mass (m), body_type (bt)
return the (body, shape) tuple for a circle
'''
given_bt = bt
bt = Body.DYNAMIC if given_bt == 'dynamic' else Body.DYNAMIC
bt = Body.STATIC if given_bt == 'static' else Body.DYNAMIC
bt = Body.KINEMATIC if given_bt == 'kinematic' else Body.DYNAMIC
moment = moment_for_circle(mass=m, inner_radius=0, outer_radius=r)
body = Body(mass=m, moment=moment, body_type=bt)
shape = Circle(body=body, radius=r)
body.position = (x, y)
return body, shape
def create_rect(w=1, h=1, scalar=1, m=1, x=0, y=0, bt=Body.DYNAMIC):
'''
given the width (w), height (h), mass (m), x-position (x), y-position (y),
scalar <to augment default square>, and the body_type (bt).
returns a `rigid body` which is a shapeless object that
has physical properties (mass, position, rotation, velocity, etc)
ALSO returns a Poly which is the Shape that really gets drawn
'''
poly_size = (w*scalar, h*scalar)
poly = Poly.create_box(body=None, size=poly_size)
# moment depends on mass and size.
# bigger poly >> bigger moment.
# more massive >> bigger moment
moment_of_inertia = moment_for_poly(m, poly.get_vertices())
body = Body(mass=m, moment=moment_of_inertia, body_type=bt)
body.position = (x, y)
poly.body = body
return body, poly
def test_create_rect():
b, s = create_rect() # get body and shape
assert type(b) == Body
assert b.body_type == Body.DYNAMIC
assert b.mass == 1
assert type(b.position) != tuple
assert b.position == (0, 0)
assert b.moment == 0.16666666666666666
assert b.shapes
assert type(b.shapes) == set
assert b.shapes.pop()
assert b.shapes.pop() == s
assert s.area == 1.0
assert s.body == b
w, h, scalar, x, y = 2, 4, 6, 8, 10
b, s = create_rect(w=w, h=h, scalar=scalar, m=1, x=x, y=y, bt=Body.STATIC)
# Body.STATIC body_type causes infinite mass and moment
assert type(b) == Body
assert b.body_type == Body.STATIC
assert str(b.mass) == 'inf'
assert type(b.position) != tuple
assert b.position == (x, y)
assert str(b.moment) == 'inf'
assert b.shapes
assert type(b.shapes) == set
assert b.shapes.pop()
assert b.shapes.pop() == s
assert s.area == (w * scalar) * (h * scalar)
assert s.body == b
pass
def test_create_circle():
assert True
pass
def test_create_segment():
assert True
pass
def test_create_triangle():
assert True
pass
def test_create_pentagon():
assert True
pass
def run_tests():
test_create_rect()
test_create_circle()
test_create_segment()
test_create_triangle()
test_create_pentagon()
print("all tests passed")
if __name__ == "__main__":
run_tests()