Impressum


Geometriefunktionen in Flash geschrieben am 12.03.2009

Hier finden sich gesammelte Funktionen für geometrische Berechnungen:

Folgende Funktionen gelten im zweidimensionales Koordinatensystem. Die Punktekoordinaten werden hier in Arrays übergeben Punkt=[Px,Py]. Alternativ könnte man es auch für Objekte umschreiben (P.x,P.y).

Schnittpunkte zweier Strahlen

ActionScript2 /* Übergabe der Punktkoordinaten im vierpunkte:Array Aufbau [[p1x,p1y],[p2x,p2y],[p3x,p3y],[p4x,p4y]] Rückgabe Array:[spx,spy] */ function geradenschnittpunkte(vierpunkte:Array):Array{ //[[P0][P1]x[P2][P3]] var a,h; var re:Array=new Array(0,0); h=((vierpunkte[3][1]-vierpunkte[2][1]) * (vierpunkte[1][0]-vierpunkte[0][0])) - ((vierpunkte[3][0]-vierpunkte[2][0]) * (vierpunkte[1][1]-vierpunkte[0][1])); if(h==0)h=1; a = (((vierpunkte[3][0]-vierpunkte[2][0]) * (vierpunkte[0][1] - vierpunkte[2][1])) - ((vierpunkte[3][1]-vierpunkte[2][1]) * (vierpunkte[0][0]-vierpunkte[2][0]))) / h; re[0]=vierpunkte[0][0] + a * (vierpunkte[1][0] - vierpunkte[0][0]); re[1]=vierpunkte[0][1] + a * (vierpunkte[1][1] - vierpunkte[0][1]); return re; }

Schnittpunkte eines Strahles mit Kreis (Sekantenpunkte)

Der Strahl ist durch zwei Punkte definiert.
ActionScript2 function kreislinieschnittpunkte(kreispos:Array,r:Number, p1:Array,p2:Array ):Array{ var r2:Number = r*r; //r² var AMY:Number = p1[1]-kreispos[1];//Richtung p1 - Kreismitte var AMX:Number = p1[0]-kreispos[0]; var AMX2:Number = AMX*AMX; var AMY2:Number = AMY*AMY; var BAY:Number = p2[1]-p1[1];//Richtung p1 - p2 var BAX:Number = p2[0]-p1[0]; var BAX2:Number = BAX*BAX; var BAY2:Number = BAY*BAY; var BAXY:Number = BAX*BAY; var AMBAX:Number = AMX*BAX; var AMBAY:Number = AMY*BAY; var vroot:Number = Math.sqrt(2*AMBAX*AMBAY + BAX2*(r2 - AMY2) + BAY2*(r2 - AMX2)); var pre:Number = AMBAX + AMBAY; var divisor:Number = BAX2 + BAY2; var t1:Number = -(pre - vroot)/divisor; var t2:Number = -(pre + vroot)/divisor; var res:Array=[[0,0],[0,0]]; res[0][0]=p1[0]+t1*BAX; res[0][1]=p1[1]+t1*BAY; res[1][0]=p1[0]+t2*BAX; res[1][1]=p1[1]+t2*BAY; return res; //NaN,NaN,NaN,NaN=keine SP ->Passante //res[0]==res[1] ->Tangente //sonst Sekante } Quelle: www.flashforum.de

Streckenlänge zwischen 2 Punkten

Die Punkte sind in p1 und p2 Arrays gespeichert [p1x,p1y][p2x,p2y]
ActionScript2 function streckenlaenge2D(p1,p2:Array):Number { return Math.sqrt( Math.pow(p2[1]-p1[1],2)+Math.pow(p2[0]-p1[0],2)); }

und zwischen 2 Punkten im 3D-Raum

function streckenlaenge3D(p1,p2:Array):Number { var a=streckenlaenge2D(p1,p2); var b=streckenlaenge2D([0,p1[2]],[0,p2[2]]); var re= Math.sqrt( a*a+b*b); return re; }

Punkt um einen anderen Punkt relativ drehen

Mit dieser Funktion wird ein Punkt um einen anderen gedreht, Winkelangabe in Grad.
ActionScript2 function drehePunkt(p:Array, dreheumPunkt:Array, Winkel:Number):Array{//Winkel in Grad var r=Winkel*Math.PI/180;//Winkel in Bogenmaß var re:Array=new Array(0,0); var flength = Math.sqrt( Math.pow(dreheumPunkt[1]-p[1],2)+Math.pow(dreheumPunkt[0]-p[0],2)); var angle = r+Math.atan2(p[1]-dreheumPunkt[1],p[0]-dreheumPunkt[0]); while(angle<0){angle = angle+2*Math.PI;} while(angle>2*Math.PI){angle = angle-2*Math.PI;} re[0]= dreheumPunkt[0]+Math.cos(angle)*flength; re[1]= dreheumPunkt[1]+Math.sin(angle)*flength; return re; }

Winkel im Schnittpunkt zweier Strecken

Winkel im Dreieck, daher von 0 bis +180
ActionScript2function getWinkel(p0,p1,p2:Array):Number{ //Winkel Strecke p0-p1 zu p1-p2 in Grad var re:Number=0; var a=streckenlaenge2D(p1,p2); var b=streckenlaenge2D(p0,p2); var c=streckenlaenge2D(p0,p1); if(a>0 && b>0 && c>0) re=Math.acos((a*a+c*c-b*b)/(2*a*c))* 180/Math.PI; return re; }
relativer Winkel 0..360
ActionScript2function getWinkelimUZS(p0,p1,p2:Array):Number{ var re:Number=0; var w1,w2; if(p0[0]==p1[0] && p0[1]<p1[1]){w1=-90;} else if(p0[0]==p1[0] && p0[1]>p1[1]){w1=90;} else if(p0[0]<p1[0] && p0[1]==p1[1]){w1=0;} else if(p0[0]>p1[0] && p0[1]==p1[1]){w1=180;} else { w1=getWinkel(p0,p1,[p0[0],p1[1]]); if(p0[0]>p1[0] && p0[1]<p1[1]) w1=w1+180; if(p0[0]>p1[0] && p0[1]>p1[1]) w1=180-w1; if(p0[0]<p1[0] && p0[1]<p1[1]) w1=w1*-1; } //in stabile Lage bringen, p0 liegt rechts von p1 var p0b=drehePunkt(p0,p1,w1); var p2b=drehePunkt(p2,p1,w1); re=getWinkel(p0b,p1,p2b); //wenn p2b in y Richtung oberhalb liegt, 360-Winkel rechnen if(p0b[1]<p2b[1])re=360-re; return re; }

Punkt auf Gerade

Gibt einen Punkt auf der Geraden zurück.
Ist pos=0 dann ist der Punkt auf p1;
ist pos=100 dann ist der Punkt auf p2;
ist pos<0 dann liegt der Punkt vor p1p2;
ist pos>100 dann liegt der Punkt nach p1p2.

ActionScript2function PunktaufGerade(p1,p2:Array,pos:Number):Array{ var re:Array=new Array(0,0); re[0]=(p2[0]-p1[0])*pos/100+p1[0]; re[1]=(p2[1]-p1[1])*pos/100+p1[1]; return re; }
Folgende Funktion verschiebt den Punkt p1 auf der Geraden die duche p1 und p2 definiert wird um Weite
ActionScript2function verschiebeP1auf(p1,p2:Array, weite:Number):Array{ var re:Array=new Array(0,0); var ax=p2[0]-p1[0];//Anstieg X var ay=p2[1]-p1[1];//Anstieg Y var p1p2=streckenlaenge2D(p1,p2); re[0]=ax/p1p2*weite+p1[0]; re[1]=ay/p1p2*weite+p1[1]; return re; }

Dreieck

Mittelpunkt (=Schwerpunkt) eines Dreieckes:
ActionScript2function mittelpunktDreieck(p1,p2,p3:Array):Array{ var re:Array=new Array(0,0); var m1:Array=streckenmittelpunkt(p2,p3); var m2:Array=streckenmittelpunkt(p1,p3); re=geradenschnittpunkte([p1,m1, p2,m2]); return re; }

Bezierkurven

Quadratische Bézierkurven
p1,p2 Anfangs und Endpunkt
p2=Stützpunkt
ActionScript2function PunktaufquadBezier(p1,p2,p3:Array, pos:Number):Array{ var re:Array=new Array(0,0); var p12=PunktaufGerade(p1,p2,pos); var p23=PunktaufGerade(p2,p3,pos); re=PunktaufGerade(p12,p23,pos); return re; }
Kubische Bézierkurven
p1,p4 Anfangs und Endpunkt
p2,p3=Stützpunkte
ActionScript2function PunktaufKubiBezier(p1,p2,p3,p4:Array, pos:Number):Array{ var re:Array=new Array(0,0); var p12=PunktaufGerade(p1,p2,pos); var p23=PunktaufGerade(p2,p3,pos); var p34=PunktaufGerade(p3,p4,pos); var s1=PunktaufGerade(p12,p23,pos); var s2=PunktaufGerade(p23,p34,pos); re=PunktaufGerade(s1,s2,pos); return re; }
Die folgende Funktion gibt den Punkt auf einer Kubischen Bezier-Kurve die durch mehrere Punkte läuft.
ActionScript2function NBezier(punkte:Array, pos:Number):Array { //punkte=Array mit Punkten [[p1x,p1y],[p2x,p2y],...] //pos 0,0..100,0 Punkt an Position var re:Array=new Array(0,0); var pa=0; var t; var strecke=0; if (pos>0 && pos<100) { for (t=0; t<punkte.length-1; t++) { strecke+=streckenlaenge2D(punkte[t],punkte[t+1]); } var streckenpos=(strecke/100*pos);//welcher Position var pas=streckenpos; //Streckenabschnitt suchen (Teilstück suchen wo der gesuchte Punkt drinnliegt) var sa=0; var svor=0; while (pas>0) { pas=pas-streckenlaenge2D(punkte[sa],punkte[sa+1]); svor+=streckenlaenge2D(punkte[sa],punkte[sa+1]); sa++; } if(sa>0){sa--;} var posaufteilstrecke=100-100/streckenlaenge2D(punkte[sa],punkte[sa+1])*(svor-streckenpos); var p1:Array=punkte[sa]; var p2:Array=new Array(0,0); var p3:Array=new Array(0,0); var p4:Array=punkte[sa+1]; var temp:Array=new Array(0,0); var w; if (sa==0) { p2=PunktaufGerade(punkte[sa],punkte[sa+1],40); } else { w=getWinkelimUZS(punkte[sa],punkte[sa-1],punkte[sa+1]); p2=PunktaufGerade(punkte[sa],punkte[sa-1],40); p2=drehePunkt(p2,punkte[sa],w+180); } if ((sa+2)==punkte.length) { p3=PunktaufGerade(punkte[sa+1],punkte[sa],40); } else { w=getWinkelimUZS(punkte[sa+1],punkte[sa],punkte[sa+2]); p3=PunktaufGerade(punkte[sa+1],punkte[sa],40); p3=drehePunkt(p3,p4,w); } re=PunktaufKubiBezier(p1,p2,p3,p4,posaufteilstrecke); } else { if (pos==0) { re=punkte[0]; } if (pos==100) { re=punkte[punkte.length-1]; } } return re; }

Bezierfunktion zum ausprobieren

Hier ist das Flash-Plugin erforderlich.



download

Alle oben genannten Funktionen und das Bezierdemo zum freien download:
beziertest.rar (8.23kb, Flash CS3)


schreibe den ersten Kommentar:


Inhalt zur freien Verwendung gibs es beim Thema Downloads.
nach oben springen
Instagram