[ascoders] Re: Punkt auf Linie finden mit ggb. Abstand zu einer Ellipse

  • From: "Mario Klingemann" <ascoders@xxxxxxxxxxxxx>
  • To: <ascoders@xxxxxxxxxxxxx>
  • Date: Sun, 8 Feb 2004 03:09:46 +0100

Das Teil hat mich nicht losgelassen. Und jetzt hab ich's juhuu!

http://www.quasimondo.com/scrapyard/ellipsecircle4.swf

Man kann es doch relativ genau berechnen. Und Dein ursprünglicher
Ansatz mußte eigentlich nur ein wenig umformuliert und umgeformt
werden:

Wir suchen den Winkel t der Ellipse, bei dem der Abstand zur Linie X ist.

Das hört sich jetzt sich nach Erbsenzählerei an, aber so ließ
sich das dann lösen. Denn der Knackpunkt um eine Funktion
daraus zu machen, war der "Abstand zur Linie".

Die Formel sieht in etwa so aus:

dx*y1 - dx*cy - dy*x1 + dy*cx + dx*ry*sin(t)
+ dy*rx*cos(t) + (dx*d*rx*sin(t)+ dy*d*ry*cos(t))
/sqrt((ry*cos(t))²+(rx*sin(t))²))=0

Aber das eigenlich fiese war, die Ableitung dieser Funktion
zu ermittlen - meine Mathekenntnisse sind dann doch
schon recht eingerostet. Die Ableitung braucht man nämlich
für die Newton-Methode um die Nullstellen zu ermitteln.

Hier ist mal der Experimentiercode. Der von der Demo ist
zu sehr in das Framework eingebunden, da macht das wenig
Sinn. Allerdings berechnet diese Version nur eine Nullstelle:

this.clear();
var x1 = 320;
var y1 = 100;
var x2 = 400;
var y2 = 500;
var dx = x2-x1;
var dy = y2-y1;
cx = 200; // Mitte der Ellipse X
cy = 200; // Mitte der Ellipse Y
rx = 100;  // X-Radius
ry = 15;  // Y-Radius
d = 50; // Abstand (Kugelradius)

this.lineStyle(2, 0);
this.moveTo(x1, y1);
this.lineTo(x2, y2);


//Das hier isr nur zum Zeichnen der Ellipse
//und ihrer Parallelkurve

for (var t = -Math.PI; t<Math.PI; t += 0.05) {
 var v1 = Math.cos(t)*ry;
 var v2 = Math.sin(t)*rx;
 this.lineStyle(2, 0xff8000);
 this.moveTo(cx+v2, cy+v1);
 this.lineTo(cx+v2, cy+v1+0.3);
 var n = d/Math.sqrt(v1*v1+v2*v2);
 px = cx+Math.cos(t)*rx+n*v1;
 py = cy+Math.sin(t)*ry+n*v2;
 this.lineStyle(1, 0x808000);
 this.moveTo(px, py);
 this.lineTo(px, py+.3);
}

var t = -Math.PI;
var iMaxIteration = 64;
var r, dr, c, s, c2, s2, cssq, sq;
var rx2 = rx*rx;
var ry2 = ry*ry;
var c1 = dx*y1-dy*x1+dy*cx-dx*cy;
var dyry = d*dy*ry;
var dxrx = d*dx*rx;
var dyrx = dy*rx;
var dxry = dx*ry;
var EPSILON = 1e-4;
// Newton Methode:
for (var i = 0; i<iMaxIteration; i++) {
 c = Math.cos(t);
 s = Math.sin(t);
 c2 = c*c;
 s2 = s*s;
 cssq = c2*ry2+s2*rx2;
 sq = Math.sqrt(cssq);

//Die Abstandsformel:
 r = c1+dyrx*c-dxry*s+(dyry*c-dxrx*s)/sq;

// Wenn nah genug an der Null - Treffer
 if (Math.abs(r)<EPSILON) {
  trace(i+" iterations");
  break;
 }

//Und ihre Ableitung:
 dr
= -dxry*c-dyrx*s+(-(dxrx*c+dyry*s)*sq-((rx2-ry2)*c*s)/sq*(dyry*c-dxrx*s))/cs
sq;
 t -= r/dr;
}

px = cx+Math.cos(t)*rx;
py = cy+Math.sin(t)*ry;
this.lineStyle(4, 0);
this.moveTo(px, py);
v1 = Math.cos(t)*ry;
v2 = Math.sin(t)*rx;
var n = d/Math.sqrt(v1*v1+v2*v2);
px = cx+Math.cos(t)*rx+n*v1;
py = cy+Math.sin(t)*ry+n*v2;
this.lineTo(px, py);


Gruß
Mario


----- Original Message ----- 
From: "André Michelle" <am@xxxxxxxxxxxxxxxxxx>
To: <ascoders@xxxxxxxxxxxxx>
Sent: Wednesday, February 04, 2004 1:26 PM
Subject: [ascoders] Punkt auf Linie finden mit ggb. Abstand zu einer Ellipse


> hi,
>
>
> es geht um Kollisionen mit Ellipsen(-segmenten). Die mathische
> Aufgabenstellung konnte ich jetzt herausextrahieren:
>
> Gegeben:
> Linie p0,p1
> Ellipse x,y,rx,ry
>
> Gesucht ist der Punkt auf einer Linie, der den Abstand X zu einer Ellipse
> hat.
>
> Folgendes konnte ich bisher selber lösen:
> Punkte auf Ellipse:
> px = Math.cos( t ) * rx;
> py = Math.sin( t ) * ry;
>
> Normalenvektor dazu:
>  var nx =  Math.cos( t) * ry;
>  var ny =  Math.sin( t) * rx;
>  var len = Math.sqrt( nx * nx + ny * ny );
>  nx /= len;
>  ny /= len;
>
> Jetzt kommt die große Umstellung der Gleichung, wo ich erstmal passen
muss.
> Ich denke, jetzt muss ich den Normalen Vektor mit dem gewünschten Abstand
> multiplizieren und mit der Linie gleichsetzen.
> Dabei erhalte ich 0,1 oder 2 Lösungen für "t" als Winkel.
>
>
> Kann das jemand schneller als ich erfassen und mir helfen ?
>
> http://andre-michelle.com/files/temp/ellipse_distance_line.swf
> http://andre-michelle.com/files/temp/ellipse_distance_line.fla <
strukturlos
> :O)
>
>
> --
> aM
>
> ------------------------------------------------------
> Archiv   : //www.freelists.org/archives/ascoders/
> Optionen : //www.freelists.org/list/ascoders
> ------------------------------------------------------
>

------------------------------------------------------
Archiv   : //www.freelists.org/archives/ascoders/
Optionen : //www.freelists.org/list/ascoders
------------------------------------------------------

Other related posts: