1
1
class Circle (object ):
2
- NumCollisions = 0 # Number of collisions in one frame
3
- NumConnections = 0 # Total number of collisions
4
- GravityAngle = 1 # Angle to gravity center in degrees
5
- GravityTheta = 1 # Angle to gravity center in radians
6
- TotalCircles = 0
7
- Gravity = 0
8
- CXV = 0
9
- CYV = 0
2
+ # Angle to gravity center (in radians).
3
+ GravityTheta = 0
4
+ # Strength of gravitational pull.
5
+ Gravity = 0.075
6
+ # Collision velocity along x axis.
7
+ xCollVel = 0
8
+ # Collision velocity along y axis.
9
+ yCollVel = 0
10
+ BgColor = color (0 )
11
+ FgColor = color (0 )
12
+ MaxDistance = 150
10
13
11
- def __init__ (self , index , x , y , xv , yv ):
14
+ def __init__ (self , index , x , y , xVel , yVel , TotalCircles ):
15
+ # Circle global ID.
12
16
self .index = index
17
+ # Circle x position.
13
18
self .x = x
19
+ # Circle y position.
14
20
self .y = y
21
+ # Circle radius.
15
22
self .radius = 2
16
- self .xv = xv
17
- self .yv = yv
18
- self .mightCollide = [1 ] * Circle .TotalCircles
19
- self .hasCollided = [1 ] * Circle .TotalCircles
20
- self .distances = [1 ] * Circle .TotalCircles
21
- self .angles = [1 ] * Circle .TotalCircles
22
- self .thetas = [1 ] * Circle .TotalCircles
23
+ # Current velocity along x-axis.
24
+ self .xVel = xVel
25
+ # Current velocity along y-axis.
26
+ self .yVel = yVel
27
+ # Storage for collisions which might happen.
28
+ self .mightCollide = [0 ] * TotalCircles
29
+ # Storage for collisions which happened.
30
+ self .didCollide = [0 ] * TotalCircles
31
+ # Storage for the distances between circles.
32
+ self .distances = [0 ] * TotalCircles
33
+ # Storage for the angle (in radians) between two connected circles.
34
+ self .thetas = [0 ] * TotalCircles
35
+ # Number of collisions in one frame.
36
+ self .numCollisions = 0
37
+ # Total number of collisions.
38
+ self .numConnections = 0
23
39
24
40
def behave (self , circles , sketchXMid , sketchYMid ):
25
41
self .move ()
@@ -28,7 +44,7 @@ def behave(self, circles, sketchXMid, sketchYMid):
28
44
self .areWeConnected (circles )
29
45
self .applyGravity (sketchXMid , sketchYMid )
30
46
self .render (circles )
31
- self .reset ()
47
+ self .resetCollisions ()
32
48
33
49
def areWeClose (self , others ):
34
50
for other in others :
@@ -47,80 +63,69 @@ def areWeColliding(self, others):
47
63
other .x , other .y )
48
64
if (self .distances [other .index ]
49
65
< (self .radius + other .radius ) * 1.1 ):
50
- self .hasCollided [other .index ] = True
51
- other .hasCollided [self .index ] = True
52
- self .angles [other .index ] = Circle .findAngle (self .x , self .y ,
53
- other .x , other .y )
54
- self .thetas [other .index ] = (- (self .angles [other .index ] * PI )) / 180.0
55
- Circle .CXV += (cos (self .thetas [other .index ])
56
- * ((other .radius + self .radius ) / 2.0 ))
57
- Circle .CYV += (sin (self .thetas [other .index ])
58
- * ((other .radius + self .radius ) / 2.0 ))
59
- Circle .NumCollisions += 1
60
- if Circle .NumCollisions > 0 :
61
- self .xv = - Circle .CXV / Circle .NumCollisions
62
- self .yv = - Circle .CYV / Circle .NumCollisions
63
- Circle .CXV = 0.0
64
- Circle .CYV = 0.0
66
+ self .didCollide [other .index ] = True
67
+ other .didCollide [self .index ] = True
68
+ self .thetas [other .index ] = self .findAngle (other .x , other .y )
69
+ Circle .xCollVel += (cos (self .thetas [other .index ])
70
+ * ((other .radius + self .radius ) / 2.0 ))
71
+ Circle .yCollVel += (sin (self .thetas [other .index ])
72
+ * ((other .radius + self .radius ) / 2.0 ))
73
+ self .numCollisions += 1
74
+ if self .numCollisions > 0 :
75
+ self .xVel = - Circle .xCollVel / self .numCollisions
76
+ self .yVel = - Circle .yCollVel / self .numCollisions
77
+ Circle .xCollVel = 0.0
78
+ Circle .yCollVel = 0.0
65
79
66
80
def areWeConnected (self , others ):
67
- maxDistance = 150
68
81
for other in others :
69
- if (self .hasCollided [other .index ]
70
- and self .index != other .index ):
82
+ if (self .didCollide [other .index ]
83
+ and other .index != self .index ):
71
84
self .distances [other .index ] = dist (self .x , self .y ,
72
85
other .x , other .y )
73
- if self .distances [other .index ] < maxDistance :
74
- self .angles [other .index ] = Circle .findAngle (self .x , self . y ,
75
- other . x , other .y )
76
- self . thetas [ other . index ] = ( - ( self . angles [ other .index ] * PI )) / 180.0
77
- Circle .CXV += cos ( self .thetas [other .index ]) * ( self . radius / 8.0 )
78
- Circle . CYV += sin ( self . thetas [ other . index ]) * (self .radius / 8.0 )
79
- Circle . NumConnections += 1
86
+ if self .distances [other .index ] < Circle . MaxDistance :
87
+ self .thetas [other .index ] = self .findAngle (other .x , other . y )
88
+ Circle . xCollVel += ( cos ( self . thetas [ other .index ] )
89
+ * ( other .radius / 8.0 ))
90
+ Circle .yCollVel += ( sin ( self .thetas [other .index ])
91
+ * (other .radius / 8.0 ) )
92
+ self . numConnections += 1
80
93
else :
81
- self .hasCollided [other .index ] = False
82
- other .hasCollided [self .index ] = False
83
- if Circle . NumConnections > 0 :
84
- self .xv += (Circle .CXV / Circle . NumConnections ) / 4.0
85
- self .yv += (Circle .CYV / Circle . NumConnections ) / 4.0
86
- Circle .CXV = 0.0
87
- Circle .CYV = 0.0
88
- self .radius = Circle . NumConnections * .85 + 2
94
+ self .didCollide [other .index ] = False
95
+ other .didCollide [self .index ] = False
96
+ if self . numConnections > 0 :
97
+ self .xVel += (Circle .xCollVel / self . numConnections ) / 4.0
98
+ self .yVel += (Circle .yCollVel / self . numConnections ) / 4.0
99
+ Circle .xCollVel = 0.0
100
+ Circle .yCollVel = 0.0
101
+ self .radius = self . numConnections * 0 .85 + 2
89
102
90
103
def applyGravity (self , sketchXMid , sketchYMid ):
91
- Circle .GravityAngle = Circle .findAngle (self .x , self .y ,
92
- sketchXMid , sketchYMid )
93
- Circle .GravityTheta = (- (Circle .GravityAngle * PI )) / 180
94
- self .xv += cos (Circle .GravityTheta ) * Circle .Gravity
95
- self .yv += sin (Circle .GravityTheta ) * Circle .Gravity
104
+ Circle .GravityTheta = self .findAngle (sketchXMid , sketchYMid )
105
+ self .xVel += cos (Circle .GravityTheta ) * Circle .Gravity
106
+ self .yVel += sin (Circle .GravityTheta ) * Circle .Gravity
96
107
97
108
def move (self ):
98
- self .x += self .xv
99
- self .y += self .yv
109
+ self .x += self .xVel
110
+ self .y += self .yVel
100
111
101
112
def render (self , others ):
102
113
noStroke ()
103
- fill (0 , 25 )
104
- ellipse (self .x , self .y , self .radius , self .radius )
105
- fill (0 + self .radius * 10 , 50 )
106
- ellipse (self .x , self .y , self .radius * 0.5 , self .radius * 0.5 )
107
- fill (0 + self .radius * 10 )
108
- ellipse (self .x , self .y , self .radius * 0.3 , self .radius * 0.3 )
109
- if Circle .NumCollisions > 0 :
114
+ self .drawMe (0 , 25 , 1 )
115
+ self .drawMe (10 , 50 , 0.5 )
116
+ self .drawMe (10 , 255 , 0.3 )
117
+ if self .numCollisions > 0 :
110
118
noStroke ()
111
- fill (0 , 25 )
112
- ellipse (self .x , self .y , self .radius , self .radius )
113
- fill (0 , 55 )
114
- ellipse (self .x , self .y , self .radius * 0.85 , self .radius * 0.85 )
115
- fill (0 )
116
- ellipse (self .x , self .y , self .radius * 0.7 , self .radius * 0.7 )
119
+ self .drawMe (0 , 25 , 1 )
120
+ self .drawMe (0 , 55 , 0.85 )
121
+ self .drawMe (0 , 255 , 0.7 )
117
122
for other in others :
118
- if (self .hasCollided [other .index ]
123
+ if (self .didCollide [other .index ]
119
124
and self .index != other .index ):
120
125
with beginShape (LINE_LOOP ):
121
126
xdist = self .x - other .x
122
127
ydist = self .y - other .y
123
- stroke (0 , 150 - self .distances [other .index ] * 2.0 )
128
+ stroke (Circle . FgColor , 150 - self .distances [other .index ] * 2.0 )
124
129
vertex (self .x , self .y )
125
130
vertex (self .x - xdist * 0.25 + random (- 1.0 , 1.0 ),
126
131
self .y - ydist * 0.25 + random (- 1.0 , 1.0 ))
@@ -129,14 +134,19 @@ def render(self, others):
129
134
vertex (self .x - xdist * 0.75 + random (- 1.0 , 1.0 ),
130
135
self .y - ydist * 0.75 + random (- 1.0 , 1.0 ))
131
136
vertex (other .x , other .y )
132
- line (self .x , self .y , other .x , other .y );
137
+ line (self .x , self .y , other .x , other .y )
133
138
noStroke ()
134
139
135
- @classmethod
136
- def reset (cls ):
137
- Circle .NumCollisions = 0
138
- Circle .NumConnections = 0
140
+ def resetCollisions (self ):
141
+ self .numCollisions = 0
142
+ self .numConnections = 0
143
+
144
+ def drawMe (self , shade , alpha , factor ):
145
+ r = self .radius * factor
146
+ fill (Circle .FgColor + self .radius * shade , alpha )
147
+ ellipse (self .x , self .y , r , r )
139
148
140
- @classmethod
141
- def findAngle (cls , x1 , y1 , x2 , y2 ):
142
- return 180 + (- (180 * (atan2 (y1 - y2 , x1 - x2 ))) / PI )
149
+ def findAngle (self , otherX , otherY ):
150
+ t = atan2 (self .y - otherY , self .x - otherX )
151
+ a = - (PI + (- t )) # PI radians
152
+ return a
0 commit comments