Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ----------------------------------------------------------------------------------------
- -- Circle Collision
- --
- -- Dynamic Circle packing
- -- Circles are placed in a domain and then push their neighbors till there are no overlaps
- --
- -- Michael Spaw
- -- Morphographic.com
- -- Started 02/05/13
- -- ver 0.01 02/08/13
- --
- -- Here are the steps for the algorithm
- -- 1. N# of circles are placed randomly within the bounding shape
- -- and the wirecolor is set to yellow
- -- 2. For each circle its closest neighbor is found
- -- 3. Based on the vector between the circle and its closest neighbor the circle
- -- is moved just a bit in the oposite dirrection
- -- 4. The neighbor and repulsion setp is looped through till there are no overlaps
- --
- -- Also of note you can see the wirecole change based on if the circle has been moved or is stationary
- ----------------------------------------------------------------------------------------
- -- Setup
- aqua = (color 87 224 198)--Create a color to be used for the bounding shape
- drawRad = 3 --the radius of the circles
- radvary = 0.7 --The amount of variation in the radius of the circles
- numcircles =200 --Total number of circles created within the test
- Iterations = 5000 --Total attemps to move the cicrcles so they no longer collide
- initxpos = 50.0-drawrad --Inital x position for the circle minus some to keep it in the bounding rectangle
- initypos = 50.0-drawrad --same for the y
- delete objects--Lets clearout all the objects before we start
- Rectangle length:100 width:100 pos:[0,0,0] wirecolor:aqua --a nice bounding rectangle for neatness
- fn blendcolor a b x =
- (
- return ((a) * (1 - (x)) + (b) * (x))
- )
- blendTime = 10
- startColor = red
- endColor = yellow
- fn setColor startColor endColor obj blendTime = (
- StartColorV = [startColor.r,startColor.g,startColor.b]
- endColorV = [endColor.r,endColor.g,endColor.b]
- colorDelta = (StartColorV - endColorV)*(1.0/blendTime) *-1
- currentColor = [obj.wirecolor.r,obj.wirecolor.g,obj.wirecolor.b]
- L = (length (endColorV - currentColor))
- if (L > (length colorDelta)) then (
- newColor = currentColor + colorDelta
- obj.wirecolor = (color newColor.x newColor.y newColor.z)
- )
- else
- (
- obj.wirecolor = endColor
- )
- )
- --Make some circles in the bounding area
- Circles= #()
- for i = 1 to numcircles do
- (
- p = (random [-initxpos,-initypos ,0.0] [initxpos,initypos,0.0])
- randRad = drawRad + (random (drawRad*-radvary) (drawRad*radvary))
- myCircle = circle pos:p radius:randRad wirecolor:startColor
- append circles myCircle
- )
- circlescolor= #()
- for i = 1 to numcircles do
- (
- circleColorVal = 0.0
- append circlescolor circleColorVal
- )
- fn findClosestNodes circles obj =
- (
- closestNodes = #()
- 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)
- if obj!=circles[i] do ( --check to make sure we aren't comparing against ourself
- (
- currDist = distance obj.pos circles[i].pos -- get the dist between comparison pairs
- if (currDist < (obj.radius+circles[i].radius)) do ( -- if the circles overlap, add to the return array
- append closestNodes circles[i]
- )
- )
- )
- )
- return closestNodes
- )
- --Time for some collision testing and movement
- for j=1 to iterations do (
- noChange = true
- for i = 1 to circles.count do (
- closestCircles = findClosestNodes circles circles[i]
- if closestCircles.count == 0 do (setColor startColor endColor circles[i] blendTime)
- for k=1 to closestCircles.count do (
- ra = circles[i].radius
- rb = closestCircles[k].radius
- rad = ra+rb
- d = distance closestCircles[k].pos circles[i].pos
- if (d < rad) do (
- noChange = false
- currentpos = circles[i].pos
- v = (closestCircles[k].pos - circles[i].pos) * -0.05
- circles[i].pos += v
- newpos = circles[i].pos
- if (newPos != currentpos) do (circles[i].wirecolor = red)
- )
- )
- )
- if noChange do (
- circles.wirecolor = yellow
- format "Number of iterations: %\n" j
- exit
- )
- forceCompleteRedraw()
- windows.processPostedMessages()
- )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement