Autor Beitrag
catweasel
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Di 23.12.08 16:11 
Hi,

ich versuche gerade eine Funktion zu basteln die feststellt ob ein Kreis und eine Strecke Schnittpunkt(e) haben. Dies sollte dann der Fall sein wenn der kuerzeste Abstand "D" von Gerade-Kreismittelpunkt nicht groesser als der Radius "R" ist, also D<=R.

Ich weiss zwar dass ich die Steigung der Strecke mit dy/dx herausbekomme und das die Geradennormale sich als Gerade mit negative Steigung (im Bezug auf die eigentlich Gerade) ermitteln laesst. Ausserdem ist einleuchtend dass D auf genau auf einer solchen Geraden liegt.


Mein Problem ist nur:

- Ich hab von vektorrechnung so viel ahnung wie ein Schimpanse von Raumfahrt. (Schonmal gemacht aber keine Ahnung gehabt was ich da eigentlich mache)...
- 85% aller googlebaren Beispiel gehen das ganze vektoriell an.
- Irgendwie verstehe ich das mit den "Hilfsebenen" in den Besispielen nicht.

Kann mir bitte jemand helfen eine Funtion zu basteln,etwa nach folgendem Schema:
(Es kann durchaus auch eine Loesung mit Vektorrechnung sein. ich verspreche auch das ich das dann zu verstehen versuche).


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
type
  TLine = record
      A : TPoint;
      B : TPoint;
    end;

type
  TSprite = record
      center : TPoint;
      radius : integer;
    end;

function collision(reflector:Tline,sprite:TSprite);
begin
// Here be Dragons
end;



Waere echt super wenn mir da jemand helfen koennte.... Es ist doch Weihnachten.... :roll:
Ich will doch so gerne das Rad neu erfinden und das beste Nachmach-Arkanoid-wo-gibt, naja jedenfalls ein Breakout-Clone schreiben... :wink:

Frohes Fest :D
-Catweasel

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
ub60
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 764
Erhaltene Danke: 127



BeitragVerfasst: Di 23.12.08 17:04 
Also es geht auch ohne Vektoren:
  • Anstieg m1 der Geraden bestimmen mit Zweipunktgleichung
  • Anstieg m2 der senkrechten Schnittgeraden bestimmen mit m2=-1/m1
  • Funktionsgleichung der zweiten Geraden bestimmen (Punkt-Anstiegs-Gleichung)
  • Schnittpunkt der beiden Geraden bestimmen (Gleichungssystem)
  • Abstand der Punkte mit Pythagoras

Ganz schöner Aufwand, ev. gehts ja einfacher :lol:

ub60
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 23.12.08 17:15 
user profile iconcatweasel hat folgendes geschrieben Zum zitierten Posting springen:
ich versuche gerade eine Funktion zu basteln die feststellt ob ein Kreis und eine Strecke Schnittpunkt(e) haben.
Das funktioniert auch ohne viel Vektorrechnung, jedenfalls ohne Skalarprodukt oder ähnlich Schreckliches ;) : www.matheboard.de/th...stid=10217#post10217
Der rein vektorielle Weg steht ein wenig drüber als letzter Punkt unter "Geraden".
Bei allen Verfahren musst du nach dem Schnitt Gerade-Kreis das Ergebnis natürlich noch auf deine Strecke übertragen.

@ub60: Und ein paar Fallunterscheidungen, wenn eine der Geraden senkrecht ist ;) .

_________________
>λ=
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Do 22.01.09 14:55 
Hi,

also ich habe mich jetzt einmal etwas damit beschaeftigt und bin zu folgendem Zwischenergebnis gekommen: Ich mach das ganze nun doch mit Vektoren. Hab mich da halt ein bischen reinlesen muessen, aber ging ganz gut.

mein Problem ist im Moment allerdings die performance. mein "Sprite" besteht aus einer TShape-Komponenete die ueber einer paintbox verschoben wird. Allerdings kriecht die Shape selbst bei einer reinen Bewegungsschleife (ohne Kollisionstetsts) nur im Schneckentempo ueber das Formular.

Ich spiele schon fast mit dem Gedanken DelphiX zu verwenden, wollte das ganze am liebsten aber ohne Harwarebeschleunigung per reinem "Software-Rendering" loesen.
Achja: Wenn ich anstelle einer Shape das Sprite (als Kreis) in die Paintbox integriere, wirds noch uebler.....

Catweasel.

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
Maweki
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 197

Ubuntu Linux
Lazarus
BeitragVerfasst: Do 22.01.09 15:59 
Wie genau hast du denn jetzt das verschieben gemacht (bisschen Code vielleicht) bzw. muss das verschieben Pixelweise passieren bzw. muss man den Vorgang sehen (sonst koennteste den Vorgang natuerlich beschleunigen, in dem du das neuzeichnen deaktivierst).

Was hast du letztendlich eigentlich vor? Vielleicht gibt es ja einen sinnvolleren/performanteren Weg.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 22.01.09 18:24 
Siehe omorphia.svn.sourcef...ry/OMathGeometry.pas

Edit:
VCL-Komponenten direkt zum Darstellen von Dingen auf der Form verwenden (gerade die TShape), da die VCL in dem Falle ein komplettes Repaint macht. Zeichne hier lieber direkt auf ein TImage oder das TCanvas der Form und kümmere dich um das Refreshen und zeichnen selbst.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Maweki
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 197

Ubuntu Linux
Lazarus
BeitragVerfasst: Do 22.01.09 19:18 
Darum habe ich gefragt. Konnte man nicht einfach
ausblenden Delphi-Quelltext
1:
2:
3:
Image1.Updating;
// Bewegung, verarbeitung, usw...
Image1.Updated;


Und in der Zwischenzeit wird das nicht neugezeichnet.

Mir war sowas wie "BeginUpdate" und "EndUpdate", aber ich sitz' hier auf Lazarus. Sollte aber eigentlich das Selbe sein.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 22.01.09 19:22 
Du kannst mit Form.Canvas.FillRect und Form.Canvas.Ellipse recht schnell zeichnen. Schau Dir zur Not auch mal Double-Buffering mit einem unsichtbaren Bitmap-Puffer an.

Alternativ: Mit Masken kann man aux XOR-basiert zeichnen; Code dafür müsst ich raussuchen ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Maweki
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 197

Ubuntu Linux
Lazarus
BeitragVerfasst: Do 22.01.09 19:28 
Double-Buffering hilft doch aber nur gegen das Flackern und ist nicht performancezuträglich.

Fakt ist:
wenn du auf eine dauernde, stetige und flüssige Bewegung aus bist, kommst du sicherlich um DirectDraw nicht herum. Die normale GDI brint's da einfach nicht.
Wenn dein Objekt im Grunde nur einmal gezeichnet wird und dann feststehend bleibt: Erst im Hintergrund zeichnen (Update verhindern) und dann im ganzen darstellen lassen.

GDI und der Versuch flüssiger Bewegungen bringt nur Kopfschmerzen.
silverhammer
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Sa 24.01.09 12:40 
Du willst wahrscheinlich keine Erklärungen und keine Diskussion über sprites und doublebuffering sondern eine fertige Funktion. Du kriegst eine fertige Funktion.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
uses
  Math;

function Abstand(L: TLine; P: TPoint): Double;
var
  VX, VY, WX, WY, W: Double;
begin
  WX := L.B.X - L.A.X;
  WY := L.B.Y - L.A.Y;
  W := hypot(WX, WY);
  if W = 0 then
    raise Exception.Create('Line.A und Line.B sind gleich und definieren daher keine Gerade !!');

  VX := P.X - L.A.X;
  VY := P.Y - L.A.Y;
  result := abs(VX*WY - VY*WX)/W;
end;


Das Ergebnis folgt aus dem minimalen Abstand von Punkt und Gerade und funktioniert daher
für alle Geraden - auch die horizontal und vertikal verlaufenden. Es muss geprüft werden
ob die Punkte A und B von L wirklich verschieden sind. Andernfalls sind, gibts eine
Fehlermeldung.

Moderiert von user profile iconKha: Delphi-Tags hinzugefügt