Einzelnen Beitrag anzeigen

Cöster

Registriert seit: 6. Jun 2006
589 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: Schnittpunkte zweier Kreise

  Alt 21. Feb 2007, 18:50
Ich hab das auch mal gebraucht und mir dazu ne Funktion geschrieben. Hat allerdings einige Macken:
  • wenn beide Mittelpunkte den gleichen Y-Wert haben, gibt's ne Division durch 0
  • wenn es keinen Schnittpunkt gibt, wird ne Wurzel aus ner negativen Zahl gezogen

Für mich hat's aber gereicht, da ich diese Fälle vorher abgefangen hab. Hier der Code mit Herleitung (wenn der Parameter Left = True ist, wird der linke Schnittpunkt zurückgeliefert, sonst der rechte (ich weiß, ist nicht so elegant, aber kannst du ja ansonsten umcoden)):

Delphi-Quellcode:
type
  TExtPoint = record
    X: Extended;
    Y: Extended;
  end;

function IntersectCircle(Center1: TExtPoint; Radius1: Extended;
  Center2: TExtPoint; Radius2: Extended; Left: Boolean): TExtPoint;
var
   m: Extended; // Steigung der Schnittpunktgeraden
   n: Extended; // Y-Achsen-Abschnitt der Schnittpunktgeraden
   p: Extended;
   q: Extended;
begin
   // m senkrecht auf dY / dX => m = -1 / (dY / dX) = - dX / dY
   m := (Center1.X - Center2.X) / (Center2.Y - Center1.Y);

   // (X - Xm)² + (Y - Ym)² - r² = 0
   // n = Y, wenn X = 0 =>
   // (1) Xm1² + n² - 2 * n * Ym1 + Ym1² - r1² = 0
   // (2) Xm2² + n² - 2 * n * Ym2 + Ym2² - r2² = 0
   // (1) - (2) Xm1² - Xm2² + Ym1² - Ym2² - r1² + r2² + 2 * n * (Ym2 - Ym1) = 0
   // => n = (Xm1² + Ym1² - r1² - Xm2² - Ym2² + r2²) / 2 / (Ym1 - Ym2)
   n := (Sqr(Center1.X) + Sqr(Center1.Y) - Sqr(Radius1) - Sqr(Center2.X) -
      Sqr(Center2.Y) + Sqr(Radius2)) / 2 / (Center1.Y - Center2.Y);

   // Y = m * X + n einsetzen in 0 = (X - Xm)² + (Y - Ym)² - r²:
   // 0 = (X - Xm)² + (m * X + n - Ym)² - r²
   // 0 = (m²+1) * X² + 2*(m*n-Xm-Ym*m) * X + Xm²+Ym²-r²+n²-2*Ym*n
   // 0 = X² + 2*(m*n-Xm-Ym*m)/(m²-1) * X + (Xm²+Ym²-r²+n²-2*Ym*n)/(m²-1)
   // p = (m*n-Xm-Ym*m)/(m²-1)
   p := (m * n - Center1.X - Center1.Y * m) / (Sqr(m) + 1);

   // 0 = X² + 2 * p * X + (Xm²+Ym²-r²+n²-2*Ym*n)/(m²-1)
   // 0 = (X + p)² - p² + (Xm²+Ym²-r²+n²-2*Ym*n)/(m²-1)
   // q = p² - (Xm²+Ym²-r²+n²-2*Ym*n)/(m²-1)
   q := Sqr(p) - ((Sqr(Center1.X) + Sqr(Center1.Y) - Sqr(Radius1) + Sqr(n) -
      2 * Center1.Y * n) / (Sqr(m) + 1));

   // 0 = (X + p)² - q => X = - p + Sqrt(q)
   // oder - p - Sqrt(q)
   if Left then
      Result.X := - p - Sqrt(q)
   else
      Result.X := - p + Sqrt(q);

   // Y = m * X + n
   Result.Y := m * Result.X + n;
end;
  Mit Zitat antworten Zitat