Ooops
January 15, 2021, 06:06:47 PM

### Author Topic: [bmx] circle to arc. by Jesse [ 1+ years ago ]  (Read 616 times)

#### BlitzBot

• Jr. Member
• Posts: 1
##### [bmx] circle to arc. by Jesse [ 1+ years ago ]
« on: June 29, 2017, 12:28:42 AM »
Title : circle to arc.
Author : Jesse
Posted : 1+ years ago

Description : OO circle to arc interaction with bounce. linear movement only, does not integrate time movement, not too difficult to integrate.

Code :
Code: BlitzMax
1. SuperStrict
2. 'Create game Object
3. Type Tgame
4.         Field stageW:Float
5.         Field stageH:Float
6.         Field maxV:Float
7.         Field gravity:Float
8.         Field LastTime:Float
9.         Field arc:TArc
10.         Field ball:Tball
11.
12.         Method New()
13.                 stageW = 480
14.                 stageH = 400
15.                 ball = Tball.Create(5,5,10,10,40)
16.                 arc = Tarc.Create(170, 195.5, 60,-60,120)
17.         End Method
18.
19.         Method update()
20.                 Local length:Float = ball.length
21.                 ball.ball2ArcCollision(arc,length)
22.         End Method
23.
24.         'Function To draw the points, lines And show text
25.         Method drawAll()
26.                 'draw ball path
27.                 'DrawLine ball.p2.x,ball.p2.y,ball.p1.x,ball.p1.y
28.                 ball.display()
29.                 arc.display()
30.         End Method
31.
32. End Type
33.
34. Type Tpoint
35.         Field x:Float
36.         Field y:Float
37. End Type
38.
39. Type Tvector
40.         Field p0:Tpoint
41.         Field p1:Tpoint
42.         Field length:Float
43.         Field dx:Float
44.         Field dy:Float
45.         Field lx:Float
46.         Field ly:Float
47.         Field vx:Float
48.         Field vy:Float
49.
50.         Field b:Float
51.         Field f:Float
52.         Field m:Float
53.         Field airf:Float
54.         Field lastTime:Float
55.         Field timeFrame:Float
56.
57.         Method New()
58.                 p0 = New Tpoint
59.                 p1 = New Tpoint
60.         End Method
61.
62.         'Function To find all parameters For the vector
63.         Method update( frompoints:Int=False)
64.                 'x And y components
65.                 If(frompoints)
66.                         vx=p1.x-p0.x
67.                         vy=p1.y-p0.y
68.                 Else
69.                         p1.x=p0.x+vx
70.                         p1.y=p0.y+vy
71.                 EndIf
72.                 'length of vector
73.                 Length=Sqr(vx*vx+vy*vy)
74.                 'normalized unit-sized components
75.                 If(Length>0)
76.                         dx=vx/Length
77.                         dy=vy/Length
78.                 Else
79.                         dx=0
80.                         dy=0
81.                 EndIf
82.         End Method
83.
84.         'find New vector bouncing from v2
85.         Method bounce:Tvector(v2:Tvector)
86.                 'projection of v1 on v2
87.                 Local dp:Float = vx*v2.dx+vy*v2.dy
88.                 Local vx1:Float = dp*v2.dx
89.                 Local vy1:Float = dp*v2.dy
90.                 'projection of v1 on v2 normal
91.                 dp = vx*v2.lx+vy*v2.ly
92.                 Local vx2:Float = dp*v2.lx
93.                 Local vy2:Float = dp*v2.ly
94.                 'reverse projection on v2 normal
95.                 Local p2l:Float = Sqr(vx2*vx2+vy2*vy2)
97.                 vx=vx1+v2.lx*p2l
98.                 vy=vy1+v2.ly*p2l
99.         End Method
100.
101.         Method display()
102.                 DrawLine p0.x,p0.y,p1.x,p1.y
103.         End Method
104. End Type
105.
106. Type Tball Extends Tvector
107.         Field vn:Tvector
108.         Field v2:Tvector
109.         Field v3:Tvector
110.         Field v:Tvector
111.         Field vbounce:Tvector
112.
113.         Field p2:Tpoint
114.
115.         Field r:Float
116.
117.         Method New()
118.
119.                  v = New Tvector
120.                 vn = New Tvector
121.                 v2 = New Tvector
122.                 v3 = New Tvector
123.                 vbounce = New Tvector
124.
125.                 p2 = New Tpoint
126.
127.         End Method
128.
129.         Function Create:Tball(x1:Float,y1:Float,x2:Float,y2:Float,r:Float)
130.                 Local b:Tball = New Tball
131.                 b.p0.x = x1
132.                 b.p0.y = y1
133.                 b.p1.x = x2
134.                 b.p1.y = y2
135.                 b.r = r
136.                 b.update(True)
137.                 Return b
138.         End Function
139.
140.         Method display()
141.                 For Local a:Float = 0 Until 360
142.                         Local vx:Float = Cos(a)*r
143.                         Local vy:Float = Sin(a)*r
144.                         Plot p0.x+vx,p0.y+vy
145.                 Next
146.         End Method
147.
148.         'find collision between balls
149.         Method ballvsBall:Tvector(pa:Tpoint, r:Float,Tlen:Float Var)
150.                 'dp for projection of vector between center of points of balls along movement vector
151.                 Local dp:Float = (pa.x-p0.x) * dx + (pa.y-p0.y) * dy
152.                 'vector To center of arc in direction of movement vectors normal
153.                 vn.p0.x = p0.x+dp*dx
154.                 vn.p0.y = p0.y+dp*dy
155.                 vn.p1.x=pa.x
156.                 vn.p1.y=pa.y
157.                 vn.update(True)
160.                 'check If vn is shorter Then combined radiuses
162.                 If (diff>0)
163.                         'collision
164.                         'amount To move back moving ball
166.                         v2.p0.x = p0.x
167.                         v2.p0.y = p0.y
168.                         v2.p1.x = vn.p0.x-moveBack*dx
169.                         v2.p1.y = vn.p0.y-moveBack*dy
170.                         v2.update(True)
171.                         'check If on the movement vector
172.                         If(v2.Length<Tlen And (v2.vx*vx+v2.vy*vy)>0)
173.                                 Return v2
174.                         EndIf
175.                 EndIf
176.                 Return Null
177.         End Method
178.
179.         'collision
180.         Method ball2ArcCollision(arc:Tarc,Tlen:Float)
181.                 'start To calculate movement
182.                 Local vx4:Float,vy4:Float,vx5:Float,vy5:Float,len5:Float
184.                 If collision
185.                         'collision point found
186.                         vx5 = collision.p1.x - arc.p0.x
187.                         vy5 = collision.p1.y - arc.p0.y
188.                         len5 = Sqr(vx5*vx5+vy5*vy5)
189.                         'check If the point is on the Right side of vector between arc points
190.                         'vector between starting point of arc And collision point
191.                         If Len5 > 0
194.                         Else
195.                                 vx4 = arc.p0.x - arc.arc.p0.x
196.                                 vy4 = arc.p0.y - arc.arc.p0.y
197.                         EndIf
198.                         If(vx4*arc.arc.dy-vy4*arc.arc.dx) >= 0
199.                                 p2.x=collision.p1.x
200.                                 p2.y=collision.p1.y
201.                                 v.vx = p2.x - arc.p0.x
202.                                 v.vy = p2.y - arc.p0.y
203.                                 v.update(False)
204.                                 vbounce.dx =  v.dy
205.                                 vbounce.dy = -v.dx
206.                                 vbounce.lx =  v.dx
207.                                 vbounce.ly =  v.dy
208.                         Else
209.                                 'Not on the arc
210.                                 collision = Null
211.                         EndIf
212.                 EndIf
213.                 'need To check with other side of arc too
214.                 If collision = Null
216.                                 'amount To move back moving ball
218.                                 Local moveForward:Float=Sqr(r*r-vn.Length*vn.Length)
219.                                 v3.p0.x = p0.x
220.                                 v3.p0.y = p0.y
221.                                 v3.p1.x = vn.p0.x+moveForward*dx
222.                                 v3.p1.y = vn.p0.y+moveForward*dy
223.                                 v3.update(True)
224.                                 'check If on the movement vector
225.                                 If(v3.Length<=Tlen And (v3.vx*vx+v3.vy*vy)>0)
226.                                         'collision point found
227.                                         vx5 = v3.p1.x - arc.p0.x
228.                                         vy5 = v3.p1.y - arc.p0.y
229.                                         len5 = Sqr(vx5*vx5+vy5*vy5)
230.                                         'check If the point is on the Right side of vector between arc points
231.                                         'vector between starting point of arc And collision point
232.                                         If len5>0
233.                                                 vx4 = (arc.p0.x+vx5/len5*arc.radius) - arc.arc.p0.x
234.                                                 vy4 = (arc.p0.y+vy5/len5*arc.radius) - arc.arc.p0.y
235.                                         Else
236.                                                 vx4 = arc.p0.x - arc.arc.p0.x
237.                                                 vy4 = arc.p0.y - arc.arc.p0.y
238.                                         EndIf
239.                                         If (vx4*arc.arc.dy-vy4*arc.arc.dx) >= 0
240.                                                 p2.x=v3.p1.x
241.                                                 p2.y=v3.p1.y
242.                                                 collision=v3
243.                                                 v.vx = p2.x - arc.p0.x
244.                                                 v.vy = p2.y - arc.p0.y
245.                                                 v.update(False)
246.                                                 vbounce.dx = -v.dy
247.                                                 vbounce.dy =  v.dx
248.                                                 vbounce.lx = -v.dx
249.                                                 vbounce.ly = -v.dy
250.
251.                                         EndIf
252.                                 EndIf
253.                         EndIf
254.
255.                         'now we need To check If endpoints of arc are being hit
256.                         Local nextCollision:Tvector = ballvsBall(arc.arc.p0, 0,Tlen)
257.                         If(nextCollision)
258.                                 If(collision=Null Or nextCollision.Length<collision.Length)
259.                                         collision = nextCollision
260.                                         p2.x=nextCollision.p1.x
261.                                         p2.y=nextCollision.p1.y
262.                                         v.vx = p2.x - arc.arc.p0.x
263.                                         v.vy = p2.y - arc.arc.p0.y
264.                                         v.update(False)
265.                                         vbounce.dx =  v.dy
266.                                         vbounce.dy = -v.dx
267.                                         vbounce.lx =  v.dx
268.                                         vbounce.ly =  v.dy
269.                                 EndIf
270.                         EndIf
271.
272.                         nextCollision=ballvsBall(arc.arc.p1, 0,Tlen)
273.                         If(nextCollision)
274.                                 If(collision=Null Or nextCollision.Length<collision.Length)
275.                                         collision=nextCollision
276.                                         p2.x=nextCollision.p1.x
277.                                         p2.y=nextCollision.p1.y
278.                                         v.vx = p2.x - arc.arc.p1.x
279.                                         v.vy = p2.y - arc.arc.p1.y
280.                                         v.update(False)
281.                                         vbounce.dx =  v.dy
282.                                         vbounce.dy = -v.dx
283.                                         vbounce.lx =  v.dx
284.                                         vbounce.ly =  v.dy
285.                                 EndIf
286.                         EndIf
287.                 EndIf
288.
289.                 If collision
290.                         Local vx1:Float = p2.x-p0.x
291.                         Local vy1:Float = p2.y-p0.y
292.                         Tlen :- Sqr(vx1*vx1+vy1*vy1)
293.                         bounce(vbounce)
294.                         p0.x = p2.x
295.                         p0.y = p2.y
296.                         update(False)
297.                         p1.x = p2.x+dx*Tlen
298.                         p1.y = p2.y+dy*Tlen
299.                         ball2ArcCollision(arc,Tlen)
300.                 Else
301.                         If (p1.x>game.stageW+r)
302.                                 p1.x = -r
303.                         Else If (p1.x<-r)
304.                                 p1.x = game.stageW+r
305.                         EndIf
306.                         If (p1.y>game.stageH+r)
307.                                 p1.y = -r
308.                         Else If (p1.y<-r)
309.
310.                                 p1.y = game.stageH+r
311.                         EndIf
312.                         p0.x = p1.x
313.                         p0.y = p1.y
314.                         update(False)
315.                 EndIf
316.         End Method
317. End Type
318.
319. Type Tarc Extends Tvector
320.         Field ang1:Float
321.         Field ang2:Float
322.         Field degrees:Float
324.         Field stp:Float
325.         Field arc:Tvector
326.
327.         Const RATE:Float = Pi/180.0
328.
329.         Method New()
330.                 arc = New Tvector
331.         End Method
332.
333.         Function Create:Tarc(x:Float,y:Float,r:Float,a1:Float,a2:Float)
334.                 Local a:Tarc = New Tarc
335.                 a.p0.x = x
336.                 a.p0.y = y
338.                 If a1 > a2
339.                         Local ta:Float = a2
340.                         a2 = a1
341.                         a1 = ta
342.                 EndIf
343.                 a.degrees = a2-a1
344.                 If a.degrees > 360
345.                         a.degrees = 360
346.                         a2 = a1+360
347.                 EndIf
348.                 a.ang1 = a1
349.                 a.ang2 = a2
350.                 a.stp = 1.0/(RATE*r)
351.                 a.findArc()
352.                 Return a
353.         End Function
354.
355.         'find End points of the arc from angles
356.         Method findArc()
357.                 'vector between End points of the arc
362.                 arc.update(True)
363.         End Method
364.
365.         Method Display()
366.                 Local Angle:Float = ang1
367.                 While Angle < (ang1+degrees)
368.                         Plot p0.x + Cos(Angle) * radius, p0.y + Sin((Angle)) * radius
369.                         Angle :+ stp
370.                 Wend
371.                 DrawOval p0.x-1,p0.y-1,2,2
372.         End Method
373.
374. End Type
375.
376. 'Create game Object
377. Global game:Tgame = New Tgame
378.
379. Graphics game.stageW,game.StageH
380. Repeat
381. Cls
382. game.update()
383. game.drawAll()
384. Flip()
385. Until KeyDown(key_escape)