AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Schnittpunkt Linie vs. Kreis

Ein Thema von Namenloser · begonnen am 25. Mär 2009 · letzter Beitrag vom 15. Okt 2012
 
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#1

Schnittpunkt Linie vs. Kreis

  Alt 25. Mär 2009, 22:12
Ich war vorhin auf der Suche nach einem Code, mit dem sich die Schnittpunkte eines Kreises und einer Linie ausrechnen lassen. Da ich für Delphi nichst gefunden habe, habe ich folgende Funktion geschrieben:
Delphi-Quellcode:
function LineHitsCircle(LineX1,LineY1,LineX2,LineY2,
  CircleX,CircleY,CircleRadius: double; out OutPos: Double): boolean;
var
  x1, x2, x: double;
  d: double;
  d_helper: double;
  m,n: double;

  tmp: double;
begin
  LineX1 := LineX1 - CircleX;
  LineY1 := LineY1 - CircleY;
  LineX2 := LineX2 - CircleX;
  LineY2 := LineY2 - CircleY;

  if (LineX2-LineX1=0) then
  begin
    if (LineY2-LineY1=0) then
    begin
      OutPos := 0.0;
      result := sqr(LineX1)+sqr(LineY1) <= sqr(CircleRadius);
      exit;
    end
    else
    begin
      tmp := LineY1;
      LineY1 := LineX1;
      LineX1 := tmp;
      
      tmp := LineY2;
      LineY2 := LineX2;
      LineX2 := tmp;
    end;
  end;

  m := (LineY2-LineY1)/(LineX2-LineX1);
  n := LineY1-m*LineX1;
  d_helper := 4*sqr(m)*sqr(n) - 4*(1+sqr(m))*(sqr(n)+2*n-sqr(CircleRadius));

  if d_helper < 0 then
  begin
    OutPos := -1;
    result := False;
  end
  else
  begin
    d := sqrt(d_helper);
    x1 := (-2*m*n - d)/(2+2*sqr(m));
    x2 := (-2*m*n + d)/(2+2*sqr(m));

    if (x1>=LineX1) and ((x1 - LineX1)<=(x2-LineX1)) then
      x := x1
    else
      x := x2;

    OutPos := abs((x-LineX1)/(LineX2-LineX1));

    result := (OutPos >= 0.0) and (OutPos <= 1.0);
  end;
end;
Sicher noch optimierbar, und gut möglich, dass es mit Vektoren irgendwie eleganter geht (das war bisher immer so ). Die Funktion gibt keinen Punkt zurück, sondern die Stelle auf der Strecke (Gleitkommazahl von 0 (Startpunkt) bis 1 (Endpunkt)), weil das für meine Zwecke praktischer ist. Man könnte aber auch sehr einfach den Punkt ausrechnen (über die lineare Funktion, m und n sind ja gegeben). Wenn es zwei Schnittpunkte gibt, wählt die Funktion den, der am nächsten beim Startpunkt liegt.
Wenn man die If-Abfragen am Ende weglässt, hat man eine Funktion, die die Schnittpunkte einer geraden und eines Kreises berechnet.

Ich hoffe, dass eine solche Funktion nicht schon gibt in der CodeLibrary existiert. Über die Suche habe ich wie gesagt nichts gefunden.

[edit]Bugfix bei senkrechter Linie[/edit]
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:17 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz