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

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

Offline 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)
  96.                 'add the projections
  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)
  158.                 'sum of radius
  159.                 Local totalRadius:Float=Self.r+r
  160.                 'check If vn is shorter Then combined radiuses
  161.                 Local  diff:Float = totalRadius-vn.Length
  162.                 If (diff>0)
  163.                         'collision
  164.                         'amount To move back moving ball
  165.                         Local moveBack:Float=Sqr(totalRadius*totalRadius-vn.Length*vn.Length)
  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
  183.                 Local collision:Tvector=ballvsBall(arc.p0, arc.radius,Tlen)
  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
  192.                                 vx4 = (arc.p0.x+vx5/len5*arc.radius)-arc.arc.p0.x
  193.                                 vy4 = (arc.p0.y+vy5/len5*arc.radius)-arc.arc.p0.y
  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
  215.                         If(vn.Length < arc.radius)
  216.                                 'amount To move back moving ball
  217.                                 Local r:Float=arc.radius-r
  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
  323.         Field radius: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
  337.                 a.radius = r
  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
  358.                 arc.p0.x = p0.x+radius*Cos(ang1)
  359.                 arc.p0.y = p0.y+radius*Sin(ang1)
  360.                 arc.p1.x = p0.x+radius*Cos(ang2)
  361.                 arc.p1.y = p0.y+radius*Sin(ang2)
  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)


Comments : none...

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal