AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte RiB - Reflect it Baby
Thema durchsuchen
Ansicht
Themen-Optionen

RiB - Reflect it Baby

Ein Thema von dizzy · begonnen am 9. Feb 2005 · letzter Beitrag vom 28. Aug 2009
Antwort Antwort
Seite 6 von 8   « Erste     456 78      
Benutzerbild von dizzy
dizzy
Registriert seit: 26. Nov 2003
Angestachelt von diesem hier hab ich mich auch mal dran gemacht.
Ziel des ganzen: Reflektion/Refraktion auch an Bezier-Splines, und additives Zeichenen um den Eindruck von Licht zu verstärken. Herausgekommen ist:

RiB
Reflect it Baby

Ein kompletter Szenen-Editor der derzeit folgende Objekte kennt:
  • Bezier-Spline-Segmente
  • Kreise
  • Emitter
Es sollen noch folgen:
  • Linien
  • Rechtecke
  • Polygone

Ein paar Hinweise zur Bedienung:
Ein selektiertes Objekt kann mit gedrückter linker Maustaste verschoben werden. Kontrollpunkte werden nicht verschoben. Das wiederum geht nur mit zusätzlich gedrückter Ctrl-Taste (dann wird der Cursor über Kontrollpunkten auch zur Hand).
Mit gedrückter Alt-Taste werden Objekte subpixelweise (1/4 Pixel) verschoben, zum Feintuning . (Lässt sich aber nicht mit Ctrl verbinden!)
Beim Emitter-Objekt ist's etwas ander: Verschieben bleibt gleich, auch das feine Verschieben, aber der Emitter lässt sich mit zusätzlich zur linken Maustaste gedrückter Ctrl-Taste drehen, und mit Shift lässt sich der Öffnungswinkel einstellen.

Nochmal in übersichtlich...
Code:
[b]Alle Objekte[/b]
[lMaus] + Ziehen         : Verschieben
[lMaus] + [Alt] + Ziehen : fein Verschieben

[b]Emitter-Objekte[/b]
[lMaus] + [Ctrl] + Ziehen : Drehen
[lMaus] + [Shift] + Ziehen: Öffnungswinkel

[b]Andere Objekte[/b]
[lMaus] + [Ctrl] + Ziehen : Zugriff auf Kontrollpunkte
Beim Bewegen der Maus über die Szene wird das Objekt, das mit einem Klick ausgewählt würde, markiert. Wenn man darunterliegende Objekte erreichen möchte, kann man mit Rechtsklicks durch alle an dieser Stelle liegenden Objekte durchschalten. Sobald das richtige markiert ist, wird es durch Linksklick selektiert.


Das Teil rechnet bei jeder Änderung der Szene alle Strahlen neu durch! Von daher sollte man sowohl mit der Strahltiefe, als auch mit der Anzahl der Strahlen aufpassen . (Leider zählt z.Zt. das bloße selektieren noch als Änderung der Szene, und löst somit ein Neuberechnen aus. Das wird noch gefixt.)

Bekannte Bugs:
  • Die Schnittpunktberechnung der Splines hat noch Schwierigkeiten mit absolut horizontalen/vertikalen Strahlen. Das hängt mit dem zu lösenden Gleichungssystem zusammen, und wird noch überarbeitet. Da der Fall aber recht selten auftritt, hat das nicht oberste Priorität.
  • Ganz selten kam es bei mir noch zu Divisionen durch Null. Deren Ursprung konnte ich noch nicht abschließend ausfindig machen, bin aber dran


Im Archiv sind Source + EXE. Viel Spaß beim Kaputttesten
Ach ja! Die Graphics32-Lib wird zum Kompilieren natürlich benötigt


Gruss,
Fabian
Miniaturansicht angehängter Grafiken
screenie_331.png  
Angehängte Dateien
Dateityp: zip rib_166.zip (252,5 KB, 609x aufgerufen)
INSERT INTO HandVonFreundin SELECT * FROM Himmel
 
Benutzerbild von turboPASCAL
turboPASCAL

 
Delphi 6 Personal
 
#51
  Alt 1. Mär 2006, 16:30
Habe das Teil heute erst gesehen, ich sag nix dazu !

Matti
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins
 
#52
  Alt 1. Mär 2006, 17:33
Dass das refracting nicht geht meinte ich so:

-Manchmal wird es etwa so refraktiert:
Code:
\  |  /
*\ | /
  \|/
   |
Was ja nun nicht dein kann. Ausserdem wird bei einer fast geraden Linie, das Licht gebrochen, wie bei einer Sammellinse ... das ist auch ein wenig unlogisch.

Aber ich würde gerne ein paar Features (wie gerade Linien) einbauen, könntest du mir einen Tipp geben, wo ich das am besten mache, damit ich nicht alle sourcen durchwühlen muss ?

Ausserdem ... könnte man das doch so machen, dass man nur 2D Objekte nimmt, dann geht das refracting auch besser ...
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

 
Delphi 7 Enterprise
 
#53
  Alt 2. Mär 2006, 00:01
Zitat von jfheins:
Dass das refracting nicht geht meinte ich so:

-Manchmal wird es etwa so refraktiert:
Code:
\  |  /
 \ | /
  \|/
   |
Was ja nun nicht dein kann. Ausserdem wird bei einer fast geraden Linie, das Licht gebrochen, wie bei einer Sammellinse ... das ist auch ein wenig unlogisch.
Jo, das ist so, weil wegen wie ichs im vorigen Beitrag geschrieben hab

Zitat von jfheins:
Aber ich würde gerne ein paar Features (wie gerade Linien) einbauen, könntest du mir einen Tipp geben, wo ich das am besten mache, damit ich nicht alle sourcen durchwühlen muss ?
Schau dir mal die Unit "Objects.pas" an. Dort sind alle Primitives drin, die RiB bisher kann, und daran siehst du auch die Schnittstelle die ein solches bieten muss. Methoden zum Erzeugen müssen dann noch der Klasse TScene hinzugefügt werden, und die Methode TScene.MouseMove() unterscheidet noch zwischen den Objekttypen. Dort müsste von dir noch rein, ob wann und wie deine Objekte als selektiert gelten sollen, und wie mit den Kontrollpunkten verfahren werden soll. Im Grunde ist die Methode ne große "if then else if then..."-Klamotte. An den existierenden Objekten sollte alles wichtige ablesbar sein (das ist zudem eines der wenigen Programme, die ich mal ordentlich kommentiert hab ^^).
Dann fehlen noch die entsprechenden Elemente für's GUI, aber das sollte dann das kleinste Problem sein denk ich.

Zitat von jfheins:
Ausserdem ... könnte man das doch so machen, dass man nur 2D Objekte nimmt, dann geht das refracting auch besser ...
Naja, das ist nicht ganz so einfach wie es zunächst klingt. Dafür müsste das Teil etwas ganz entscheidendes dazu lernen: Ein Strahl muss zu jedem Punkt wissen, wie der Brechugnsindex des Materials ist, in dem er sich soeben befindet. Aus dem Unterschied der Indezes an einem Übergangspunkt würde sich dann die Brechung errechnen. Das hab ich jedoch in dieser Komplexität hier garnicht vorgesehen (das Prog war schon zu weit als mir das bewusst wurde). Wie gesagt: Das ist 1a eine Designschwäche, und auch einer der wichtigen Erkenntnisse die ich an dem Teil gewonnen hab ^^.
Fabian K.
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins
 
#54
  Alt 2. Mär 2006, 13:32
Ok, ich bin jetzt soweit:
Delphi-Quellcode:
  TLineObj = class(TSceneObject)
  protected
    procedure SetColor(v: TColor32); override;
    function GetColor: TColor32; override;
  public
    Line: TLine;
    SelPoint: Integer;
    constructor Create(Owner: TScene; x1, y1, x2, y2: Single; FX: TEffect; Color: TColor32);
    procedure Draw; override;
    function GetIntersects(a, b: TFloatPoint): TZS; override;
    procedure Changed; override;
  end;

constructor TLineObj.Create(Owner: TScene; x1, y1, x2, y2: Single; FX: TEffect; Color: TColor32);
begin
  inherited Create(Owner, FX, Color);

  Line.a.X := x1;
  Line.a.Y := y1;
  Line.b.X := x2;
  Line.b.Y := y2;

  Changed;
end;

procedure TLineObj.Changed;
begin
  Rect.Left := Min (Line.a.X, Line.b.X) - 5;
  Rect.Right := Max (Line.a.X, Line.b.X) + 5;
  Rect.Top := Min (Line.a.Y, Line.b.Y) - 5;
  Rect.Bottom := Max (Line.a.Y, Line.b.Y) + 5;
end;

procedure TLineObj.Draw;
var
  c: TColor32;
begin
  if isSelected then
  begin
    FOwner.FObjectBMP.Canvas.Pen.Color := clRed;
    FOwner.FObjectBMP.Canvas.Brush.Color := clRed;

    FOwner.FObjectBMP.Canvas.Rectangle(round(Line.a.X)-4,
                                       round(Line.a.Y)-4,
                                       round(Line.a.X)+4,
                                       round(Line.a.Y)+4);

    FOwner.FObjectBMP.Canvas.Rectangle(round(Line.b.X)-4,
                                       round(Line.b.Y)-4,
                                       round(Line.b.X)+4,
                                       round(Line.b.Y)+4);


  end;


  if isSelected then c := Color32(255,255,255)
  else c := self.FColor;


    FOwner.FObjectBMP.LineFS(Line.a.X,
                             Line.a.Y,
                             Line.b.X,
                             Line.b.Y,
                             c);
end;

procedure TLineObj.SetColor(v: TColor32);
begin
  FColor := v;
end;

function TLineObj.GetColor: TColor32;
begin
  result := FColor;
end;

function TLineObj.GetIntersects(a, b: TFloatPoint): TZS;
begin
//
end;
In der GetIntersects-Methodem muss ich eventuelle überschneidungen zurückliefern, oder ?
(In weiser (?) Vorraussicht auch: http://www.delphipraxis.net/internal...ct.php?t=76738 )
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

 
Delphi 7 Enterprise
 
#55
  Alt 2. Mär 2006, 15:19
Zitat von jfheins:
In der GetIntersects-Methodem muss ich eventuelle überschneidungen zurückliefern, oder ?
(In weiser (?) Vorraussicht auch: http://www.delphipraxis.net/internal...ct.php?t=76738 )
Jopp. Du bekommst mit a und b die beiden Punkte der Strecke mit der dein Objekt geschnitten werden soll, und das Ergebnis wird in der TZS-Struktur zurückgegeben.
Fabian K.
  Mit Zitat antworten Zitat
Meriones
 
#56
  Alt 14. Mär 2007, 22:02
Hallo dizzy, habe das ray trace programm gesehen und bin begeistert.


Ich bin gerade dabei ein Programm zur Rekonstruktion mikroskopischer Schnitte zu schreiben. Dazu brauche ich Splines!
In deinem Programm sind die Splines wunderbar implemetiert!!! Allerdings nur Start- und Endpunkt mit zwei Kontrollpunkten.
Mir schwebt eine geschlossene Spline Kurve mit beliebig vielen Punkten und zugehörigen Kontrollpukten vor (so ala Freehand, CorellDraw oder Illustrator). Ich frage mich jetzt wie man soetwas implementiert. Momentan benutze ich OpenGL da das automatisch die Kurve rendered . Wenn ich da allerings ein Spline höheren Grades (sagen wir 5) erstelle liegen wieder nur start und enpunkt auf der Linie, die restlichen Punkte sind Kontrollpunkte und "ziehen" die Kurve nur an. Ich brauche aber eine Linie mit beliebig vielen punkten, die jeweils durch Kontrollpunkte kontroliert werden.

Hat jemand eine Idee???
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

 
Delphi 7 Enterprise
 
#57
  Alt 15. Mär 2007, 02:53
Bezier-Splines haben grundsätzlich zur Eigenschaft, dass alle Punkte ausser den Randpunkten keine Durchgangspunkte der Kurve sind (ausser man legt es darauf an, z.B. bei einer Geraden). Es gibt Spline Verfahren, die das ermöglichen, aber man geht in fast jeder Grafik Suite die ich kenne so vor, dass man Bezier-Spline Segmente mit je 4 Kontrollpunkten aneinander stückelt.
Das hat den großen Vorteil, dass die beiden mittleren Punkte mit ihrem jeweiligen am selben Ende liegenden Endpunkt verbunden, die Tangente in den Endpunkten darstellen. Dadurch kann man recht einfach erreichen, dass die Kurve an den Übergangsstellen wirklich weich ist, ja sogar differenzierbar 8). Du musst nur die Tangenten zweier Segmente im Berührungspunkt auf eine Gerade bekommen.
Das bietet dann also nicht nur gute Kontrolle über die grobe Form, sondern auch über die Art der "Ecken", bzw. die Ausprägung der Rundung in selbigen.

Bezier
Fabian K.
  Mit Zitat antworten Zitat
alzaimar

 
Delphi 2007 Enterprise
 
#58
  Alt 15. Mär 2007, 07:51
Splines, die durch Kontrollpunkte verlaufen, lassen sich relativ einfach berechnen. Im Prinzip sind es polynome 3.Grades, die durch die einzelnen Punkte laufen. Betrachten wir drei Punkte P[i-1], P[i] und P[i+1]. Ein Spline durch diese Punkte besteht aus 2 Polynomen. PN1 geht von P[i-1] zu P[i] und PN2 geht von P[i] zu P[i+1].

Die beiden Polynome müssen am Punkt P[i] in ihrer 1. und 2.Ableitung gleich sein, damit keine Stufen entstehen und das Ganze glatt verläuft.

Wir wissen also:
1. PN1'(x[i]) = PN2'(x[i]) // gleiche Steigung
2. PN1''(x[i]) = PN2''(x[i])

Ich weiss nicht mehr, wieso, aber ich habe alle Polynome nicht von x[i]...x[i+1], sondern von 0... x[i+1]-x[i] laufen lassen.

Damit ergeben sich folgende Bedingungen (sei dx0 = x[i]-x[i-1] und dx1 = x[i-1] - x[i]):
1. PN1[0] = y[i-1]
2. PN2[0] = y[i]
3. PN1[dx0] = y[i]
4. PN2[dx1] = y[i+1]

Wir haben nun 6 Gleichungen für 8 unbekannte (2x 4 Koeffizienten für die Polynome). 2 fehlen noch. der nächste Abschnitt liefert uns jedoch die fehlenden 2 Gleichungen (für PN2) und so weiter. Wenn man das Gleichungssystem für alle Punkte in eine Matrix schreibt, erhält man M-2 Gleichungen mit M Unbekannten. Fast fertig. Nun kann man einfach definieren, das PN0"(0) = 0 und PNn"(dxn) = 0, also setzt einfach die 2.Ableitung am ersten Punkt und die am letzten Punkt auf 0.

Somit ist das Gleichungsystem vollständig und man kann es mit einfachen Mitteln lösen. Dann erhält man N 4-tupel, die Koeffizienten der Polynome.

Kleiner Haken: Die Sache klappt nur bei streng monoton steigenden X-Werten.

Um nun beliebige Kurven zu zeichnen, Erstellt man zwei Splines:
Eins für die Punkte x[i],z[i] und eins für die Punkte y[i],z[i], wobei z[i] eine streng monoton steigende Hilfsfunktion ist, z.B. der Abstand zwischen den einzelnen Punkten aufsummiert. Abschließend berechnet man die Splines S1 und S2 und trägt die Werte S1 S2 auf. Fertig ist die glatte Kurve.

Leider hab ich den Sourcecode nicht auf meinem Laptop, sondern -wenn überhaupt- nur uff Aaabeet. Aber das selbst ich das vor 10-15 Jahren mal hinbekommen habe, schaffst Du das auch: Einfach mal 10 Minuten sacken lassen, Gleichungssystem aufschreiben und lösen (lassen).
  Mit Zitat antworten Zitat
Pfoto

 
Turbo Delphi für Win32
 
#59
  Alt 15. Mär 2007, 08:10
Hut hab zu dem Teil!
Toll, wenn man Mathematik beherrscht... aber das muss man wohl auch in die Wiege gelegt bekommen haben

Weiter so!

Gruß
Pfoto
Jürgen Höfs
  Mit Zitat antworten Zitat
alzaimar

 
Delphi 2007 Enterprise
 
#60
  Alt 15. Mär 2007, 09:20
Hier mein uralter TP-Code. Wer es unter Delphi zum Laufen bringt, kann und sollte es hier auch posten.

[edit] Ich hatte immer ne 3 oder 4 in Mathe. Im Studium bin ich gerade so durch die Prüfung gerauscht. Aber über die Jahre muss man sich mit dem Zeugs nun mal auseinandersetzen. Und so schwer ist das ja nicht.[/edit]
Angehängte Dateien
Dateityp: pas splines_133.pas (4,1 KB, 26x aufgerufen)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 6 von 8   « Erste     456 78      


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:34 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