Advertisement
Guest User

CircleCollision_01

a guest
Nov 4th, 2014
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.16 KB | None | 0 0
  1.     ----------------------------------------------------------------------------------------
  2.     --  Circle Collision
  3.     --
  4.     --  Dynamic Circle packing
  5.     --  Circles are placed in a domain and then push their neighbors till there are no overlaps
  6.     --
  7.     --  Michael Spaw
  8.     --  Morphographic.com
  9.     --  Started 02/05/13
  10.     --  ver 0.01 02/08/13
  11.     --
  12.     --  Here are the steps for the algorithm
  13.     --  1. N# of circles are placed randomly within the bounding shape
  14.     --    and the wirecolor is set to yellow
  15.     --  2. For each circle its closest neighbor is found
  16.     --  3. Based on the vector between the circle and its closest neighbor the circle
  17.     --      is moved just a bit in the oposite dirrection
  18.     --  4. The  neighbor and repulsion setp is looped through till there are no overlaps
  19.     --   
  20.     --  Also of note you can see the wirecole change based on if the circle has been moved or is stationary
  21.     ----------------------------------------------------------------------------------------
  22.    
  23.     -- Setup
  24.     aqua = (color 87 224 198)--Create a color to be used for the bounding shape
  25.     drawRad = 3 --the radius of the circles
  26.     radvary = 0.7 --The amount of variation in the radius of the circles
  27.     numcircles =200 --Total number of circles created within the test
  28.     Iterations = 5000 --Total attemps to move the cicrcles so they no longer collide
  29.  
  30.     initxpos = 50.0-drawrad --Inital x position for the circle minus some to keep it in the bounding rectangle
  31.     initypos = 50.0-drawrad --same for the y
  32.  
  33.     delete objects--Lets clearout all the objects before we start
  34.  
  35.     Rectangle length:100 width:100 pos:[0,0,0] wirecolor:aqua  --a nice bounding rectangle for neatness
  36.  
  37.     fn blendcolor a b x =
  38.     (
  39.         return ((a) * (1 - (x)) + (b) * (x))
  40.     )
  41.  
  42.     blendTime = 10
  43.     startColor = red
  44.     endColor = yellow
  45.  
  46.     fn setColor startColor endColor obj blendTime = (
  47.             StartColorV = [startColor.r,startColor.g,startColor.b]  
  48.             endColorV = [endColor.r,endColor.g,endColor.b]
  49.             colorDelta = (StartColorV - endColorV)*(1.0/blendTime) *-1
  50.             currentColor = [obj.wirecolor.r,obj.wirecolor.g,obj.wirecolor.b]
  51.             L = (length (endColorV - currentColor))
  52.             if (L > (length colorDelta)) then (
  53.                 newColor = currentColor + colorDelta
  54.                 obj.wirecolor = (color newColor.x newColor.y newColor.z)
  55.             )
  56.                 else
  57.             (
  58.                 obj.wirecolor = endColor
  59.             )
  60.     )
  61.  
  62.     --Make some circles in the bounding area
  63.     Circles= #()
  64.     for i = 1 to numcircles do
  65.     (
  66.         p = (random [-initxpos,-initypos ,0.0] [initxpos,initypos,0.0])
  67.         randRad = drawRad + (random (drawRad*-radvary) (drawRad*radvary))
  68.         myCircle = circle pos:p radius:randRad wirecolor:startColor
  69.          append circles myCircle
  70.     )
  71.  
  72.     circlescolor= #()
  73.     for i = 1 to numcircles do
  74.     (
  75.         circleColorVal = 0.0
  76.         append circlescolor circleColorVal
  77.     )
  78.  
  79.     fn findClosestNodes circles obj =
  80.     (
  81.         closestNodes = #()
  82.         for i=1 to circles.count do ( -- loop through the circles to find any that are within the radius of the circle in question (obj)
  83.             if obj!=circles[i] do ( --check to make sure we aren't comparing against ourself
  84.                 (
  85.                     currDist = distance obj.pos circles[i].pos -- get the dist between comparison pairs
  86.                     if (currDist < (obj.radius+circles[i].radius)) do ( -- if the circles overlap, add to the return array
  87.                         append closestNodes circles[i]
  88.                     )
  89.                 )
  90.             )
  91.         )
  92.         return closestNodes
  93.     )
  94.  
  95.     --Time for some collision testing and movement
  96.     for j=1 to iterations do (
  97.         noChange = true
  98.         for i = 1 to circles.count do (
  99.             closestCircles =  findClosestNodes circles circles[i]
  100.             if closestCircles.count == 0 do (setColor startColor endColor circles[i] blendTime)
  101.             for k=1 to closestCircles.count do (
  102.                 ra = circles[i].radius
  103.                 rb = closestCircles[k].radius
  104.                 rad = ra+rb
  105.                 d = distance closestCircles[k].pos circles[i].pos
  106.                 if (d < rad) do (
  107.                     noChange = false
  108.                     currentpos = circles[i].pos
  109.                     v = (closestCircles[k].pos - circles[i].pos) * -0.05
  110.                     circles[i].pos += v
  111.                     newpos = circles[i].pos
  112.                     if (newPos != currentpos) do (circles[i].wirecolor = red)
  113.                 )
  114.             )
  115.         )
  116.         if noChange do (
  117.             circles.wirecolor = yellow
  118.             format "Number of iterations: %\n" j
  119.             exit
  120.         )
  121.         forceCompleteRedraw()
  122.         windows.processPostedMessages()
  123.     )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement