AS3 - Automatically fill lineTo when it makes a closed loop

I looked at the Avoider code for Emanuele Feronato (code and link below) and try to adapt it so that when the line intersects on its own - it makes a closed loop - it fills only that area see the image . My maths are terrible, and I'm struggling to figure out the trigger. Any suggestions? Thanks.

Here is a diagram explaining - http://samtripp.com/eg.png

LINK: http://www.emanueleferonato.com/2011/10/13/develop-a-flash-game-like-string-avoider-as3-version-and-more/

package { import flash.display.Sprite; import flash.events.Event; import flash.geom.Point; public class Main extends Sprite { private var tailLenght:Number=50; private var tailNodes:Number=10; private var head:headMc=new headMc(); private var tailCanvas:Sprite=new Sprite(); private var nodes:Vector.<Point>=new Vector.<Point>(); public function Main() { addChild(head); head.x=320; head.y=240; addChild(tailCanvas); for (var i:int=0; i<tailNodes; i++) { nodes[i]=new Point(head.x,head.y); } addEventListener(Event.ENTER_FRAME,update); } private function update(e:Event):void { head.x=mouseX; head.y=mouseY; tailCanvas.graphics.clear(); tailCanvas.graphics.lineStyle(2,0x00ff00); tailCanvas.graphics.moveTo(head.x,head.y); nodes[0]=new Point(head.x,head.y); for (var i:int=1; i<tailNodes-1; i++) { var nodeAngle:Number=Math.atan2(nodes[i].y-nodes[i-1].y,nodes[i].x-nodes[i-1].x); nodes[i]=new Point(nodes[i-1].x+tailLenght*Math.cos(nodeAngle),nodes[i-1].y+tailLenght*Math.sin(nodeAngle)); if (i<tailNodes-2) { for (var j:int=i-1; j>=1; j--) { var p:Point=lineIntersection(nodes[j],nodes[j-1],nodes[i],nodes[i+1]); if (p!=null) { tailCanvas.graphics.beginFill(0x000000); tailCanvas.graphics.drawCircle(px,py,4); tailCanvas.graphics.endFill(); tailCanvas.graphics.moveTo(nodes[i-1].x,nodes[i-1].y); } } } tailCanvas.graphics.lineTo(nodes[i].x,nodes[i].y); } } private function lineIntersection(p1:Point,p2:Point,p3:Point,p4:Point):Point { var x1:Number=p1.x; var x2:Number=p2.x; var x3:Number=p3.x; var x4:Number=p4.x; var y1:Number=p1.y; var y2:Number=p2.y; var y3:Number=p3.y; var y4:Number=p4.y; var px:Number=((x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4))/((x1-x2)*(y3-y4)-(y1-y2)*(x3-x4)); var py:Number=((x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4))/((x1-x2)*(y3-y4)-(y1-y2)*(x3-x4)); var segment1Len:Number=Math.pow(p1.x-p2.x,2)+Math.pow(p1.y-p2.y,2); var segment2Len:Number=Math.pow(p3.x-p4.x,2)+Math.pow(p3.y-p4.y,2); if (Math.pow(p1.x-px,2)+Math.pow(p1.y-py,2)>segment1Len) { return null; } if (Math.pow(p2.x-px,2)+Math.pow(p2.y-py,2)>segment1Len) { return null; } if (Math.pow(p3.x-px,2)+Math.pow(p3.y-py,2)>segment2Len) { return null; } if (Math.pow(p4.x-px,2)+Math.pow(p4.y-py,2)>segment2Len) { return null; } return new Point(px,py); } } 

}

+4
source share
1 answer

On this site you can find many good tutorials. I recommend it.

Just wrote a quick function that does what you are looking for:

 private function fillIntersection(p,startN,endN):void{ tailCanvas.graphics.beginFill(0x0000FF,0.5); tailCanvas.graphics.moveTo(px,py); for (var i:int=endN; i<startN; i++) { tailCanvas.graphics.lineTo(nodes[i].x,nodes[i].y); } tailCanvas.graphics.lineTo(nodes[startN].x,nodes[startN].y); tailCanvas.graphics.endFill(); } 

And you should run this after: if (p!=null) { (line 34)

Same:

 if (p!=null) { fillIntersection(p,i,j); tailCanvas.graphics.beginFill(0x000000); 

To explain how this works, the functions specify the points of the line to fill and the exact point of collision, then it passes through them and draws a filled polygon.

(I'm sure there are better ways to do this, but it works and is easy to understand)

+2
source

All Articles