![]() |
Kollision mit Farbe
Tag auch, hoffe die Frage ist nicht zu trivial, aber wie schafft man es, dass eine Kugel (hab ich schon) mit einem Shape kollidiert?
Wenn ich es so mache, dass ich die Distanz zwischen Shape und Kugel prüfe klappt auch alles wunderbar, nur wäre es besser, wenn er nicht auf das shape direkt reagiert, sondern eher auf die farbe. Am besten wäre die Farbe "unter" der Kugel (mx,my). Kann man die irgendwie abrufen wenn die kugel sich selbst darüber befindet? Ach ja, kann man einfach ein Rechteck mit canvas auf die Form zeichnen OHNE image/paint Feld? Ein Error kommt zwar nicht wenn ich es versuche, aber das Rechteck auch nicht. Hoffe mein WirrWarr an Fragen war einigermaßen verständlich und es erbarmt sich jemand, mir zu helfen . :thumb: |
Re: Kollision mit Farbe
Durch die erste Frage bin ich jetzt nicht ganz durchgestiegen.
Zur zweiten Frage: Auf OnPaint reagieren und dann mit Rectangle(X1,Y1,X2,Y2) zeichnen. |
Re: Kollision mit Farbe
Zitat:
Zitat:
Eine PaintBox zeichnet letztlich auch auf den Canvas des Formulars (hat also keinen eigenen). |
Re: Kollision mit Farbe
Ok, das mit OnPaint habe ich jetzt.
Auch wenn es ein Rückschritt ist, habe ich sonst keine Idee wie ich es sonst machen sollte. Es geht um den Tascheneinlauf beim Snooker/Billard. Und den kann ich mit Shapes nicht sonderlich gut darstellen, weshalb ich ihn als Bild etc einfügen/zeichnen wollte und die Kollision dann mit den Pixeln machen. :gruebel: Irgendwie habe ich mich darauf festgebissen, komme einfach auf keine andere Idee als die Pixelkollision. |
Re: Kollision mit Farbe
Pixelabfragen sind aber seh unperformant und man kann auch schnell mal was übersehn.
Abgesehn davon ist es nicht einfach von einem Canvas die Pixelfarbe abzufragen, wenn wenn mal irgendwas über dem Pixel ist, dann gibt es diese Farbe nicht mehr. Nimm den Mittelpunkt der Kugel und einen oder mehrere Punkte innerhalb der Taschen und rechne dir die Abständer der Punkte aus. Ist einer der Abständer kleiner als die entsprechenden Radien, dann ist der "Ball" drinnen. |
Re: Kollision mit Farbe
Gut, werde das mal so versuchen. Bringt mich aber zur nächsten Frage, wie/ob man die Stärke der Rundung der gerundeten Rechtecke abfragen/verändern kann.
Edit: ok, ich glaube, diese Frage hat sich erledigt. Edit: oder auch nicht :(. Mit canvas kein Problem, aber kann man das auch bei Shapes direkt einstellen? |
Re: Kollision mit Farbe
Ist der Punkt im Kreis: x² + y² < r²
|
Re: Kollision mit Farbe
Hmm, neues Problem.
Wenn ich versuche, einen Ball von einer beliebigen Seite eines Shapes (Rechteck) zurückzuwerfen, verfangen sich die Bälle am Shape und "zappeln" hin und her.
Code:
V sind die Geschwindigkeiten, r der Radius, x/y der Mittelpunkt des Balls.
if (x-(shape1.Left+shape1.width)<=r) and (y>=shape1.top)and(y<=shape1.top+shape1.height)and (vx<0)
then vx := -vx*reibungbande; //von rechts nach links if (Y-(shape1.top+shape1.height)<=R) and (x>=shape1.left)and(x<=shape1.Left+shape1.Width) and (vy<0) then vy := -vy*reibungbande; //unten oben if ((shape1.left)-x <= r)and(y>=shape1.top)and(y<=shape1.top+shape1.height)and (vx>0) then vx := -vx*reibungbande; //links rechts if (shape1.Top-y<=r) and (x>=shape1.left)and(x<=shape1.Left+shape1.Width) and (vy>0) then vy := -vy*reibungbande; //oben unten Wenn ich beide horizontalen oder vertikalen Abfragen gleichzeitig aktiviere kommt das Problem, und ich hab leider keine Idee, wie ich das verhindern kann. |
Re: Kollision mit Farbe
Es gibt die möglichkeit mit Vektorrechnung herauszufinden, ob der Ball sich denn momentan auch wirklich
auf das Objekt zubewegt, mit dem er wohl kollidiert. Ich hab das selbst mal so gemacht. Dazu nimmt man das Punkt-Produkt aus Abstand(Ball <-> Mittelpunkt des Objektes) und dem Geschwindigkeitsvektor des Balles
Delphi-Quellcode:
ANMERKUNG: Weil ich das jetzt nicht nachgeprüft hab, könnte es auch sein das da anstatt "< 0" stattdessen
If VectorDotProduct(VectorSub(Ball.Pos, Object.Pos), Ball.vel) < 0 then
begin [...] end; "> 0" stehen muss. MFG |
Re: Kollision mit Farbe
Du kannst als sehr einfache Lösung den Ball bei Kollision einfach manuell an den Rand des Shapes zurechtschieben. Einfach in Richtung des neuen Vektors um die Länge (R1+R2)-||M2-M1||+e von seiner Position aus, oder von M1 aus um die Länge R1+R2+e verschieben. (M1=Mittelpunkt des Kollisionspartners; M2=Mittelpunkt des Balls; R1=Radius des Kollisionspartners; R2=Radius des Balls; e=epsilon, sehr kleiner Wert um zu umgehen, dass kleinste Rechenungenauigkeiten bei Floats dazu führen, dass die Verschiebung ganz knapp zu kurz ausfällt; ||x||=Länge von x)
Der ganz korrekte Weg wäre es festzustellen ob eine Kollision passieren wird, bevor du die Verschiebung ausführst. Durch Berechnung des Schnittpunktes weisst du genau wo (bzw. wann) die Kollision zwischen den Schritten auftritt, und du kannst den Restvektor zum Shape-Rand (V1) sowie den verbleibenden Anteil des reflektierten Vektors (V2) berechnen. Dann verschiebst du nachher um V1+V2, gibst aber dem Ball die Geschwindigkeit Norm(V2)*(||V1||+||V2||)*k (k=Konstante die den Energieverlust beim Stoß beschreibt), bzw. Norm(V2)*||V0||*k (V0=Geschwindigkeit des Balls vor der Kollision). |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz