AGB  ·  Datenschutz  ·  Impressum  







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

Bezierkurven

Ein Thema von rawsoul · begonnen am 26. Dez 2006 · letzter Beitrag vom 30. Dez 2006
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von rawsoul
rawsoul

Registriert seit: 29. Okt 2006
Ort: Düsseldorf
249 Beiträge
 
Delphi 2005 Personal
 
#1

Bezierkurven

  Alt 26. Dez 2006, 14:42
Hallo Ihr lieben Delphianer,

Ich möchte mir z. Zt. aus reinem Interess ein Programm schreiben, welches eine quadratische Bezierkurve in eine PainBox zeichnen soll. Habe mich schon mühselig durch das halbe Forum (Achtung: übertrieben!) gesucht, aber leider nichts gefunden.

Bräuchte wenigstens einen ersten Ansatzpunkt für die ganze Geschichte.
Hier mal das von Wiki geklaute Bild zur Funktion einer B-Kurve:
http://upload.wikimedia.org/math/4/a...d1cd0be79c.png

Bin für jeden hilfreichen Tipp Dankbar!

LG, und ein (nachträglich) frohes Fest an alle!
Frank Dumont
  Mit Zitat antworten Zitat
Ratte

Registriert seit: 12. Dez 2003
Ort: Erfurt
345 Beiträge
 
Delphi 2005 Personal
 
#2

Re: Bezierkurven

  Alt 26. Dez 2006, 15:09
Delphi-Quellcode:
i:integer;
p0,p1,p2:TPoint;
self.Canvas.MoveTo(P0.x,P0.y);
for i := 0 to 1000 do
  begin
    hx:=round(sqr(1-i/1000)*P0.X+2*i/1000*(1-i/1000)*P1.X+sqr(i/1000)*P2.X);
    hy:=round(sqr(1-i/1000)*P0.y+2*i/1000*(1-i/1000)*P1.y+sqr(i/1000)*P2.y);
    self.Canvas.LineTo(hx,hy);
  end;
So funzt es bei mir, vorrausgesetzt mein Grundansatz ist richtig (habs mir in den letzten 10 min schnell erarbeitet, aber es sieht wie ne bezierkurve aus und erscheint mir logisch).
mfg,
Ratte
Schiffsratte der U.S.S. Delphipraxis, Laderaum 4538
BUSH:= TTerminator.create;
  Mit Zitat antworten Zitat
Benutzerbild von rawsoul
rawsoul

Registriert seit: 29. Okt 2006
Ort: Düsseldorf
249 Beiträge
 
Delphi 2005 Personal
 
#3

Re: Bezierkurven

  Alt 26. Dez 2006, 15:17
danke, bin schonmal tausend denkschritte weiter :]

hm, bei mir zeichnet er nur eine lineare strecke von p0 nach (hx,hy) ???
hab ich da was falsch gemacht?
Frank Dumont
  Mit Zitat antworten Zitat
Ratte

Registriert seit: 12. Dez 2003
Ort: Erfurt
345 Beiträge
 
Delphi 2005 Personal
 
#4

Re: Bezierkurven

  Alt 26. Dez 2006, 15:25
öhm. p0 ist der anfangspunkt, p1 der "hilfspunkt" und p2 der endpunkt. Also bei mir hats funktioniert.

EDIT:
Hier mal etwas mehr QT:
Delphi-Quellcode:
var
  Form1: TForm1;
  state:byte;
  p0,p1,p2:TPoint;

implementation

{$R *.nfm}

procedure TForm1.Neu1Click(Sender: TObject); //Neue Kurve zeichnen
begin
state:=0;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
state:=0;
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var i,hx,hy:integer;
begin
case state of
0:
begin
  state:=1;
  P0.X:=X;
  P0.Y:=Y;
end;
1:
begin
  state:=2;
  P1.X:=X;
  P1.Y:=Y;
end;
2:
begin
  state:=3;
  P2.X:=X;
  P2.Y:=Y;
  self.Canvas.MoveTo(P0.x,P0.y);
  for i := 0 to 1000 do
  begin
    hx:=round(sqr(1-i/1000)*P0.X+2*i/1000*(1-i/1000)*P1.X+sqr(i/1000)*P2.X);
    hy:=round(sqr(1-i/1000)*P0.y+2*i/1000*(1-i/1000)*P1.y+sqr(i/1000)*P2.y);
    self.Canvas.LineTo(hx,hy);
    state:=0;
  end;
end;
end;
end;
durhc 3x klicken werden die Punkte festgelegt.
Schiffsratte der U.S.S. Delphipraxis, Laderaum 4538
BUSH:= TTerminator.create;
  Mit Zitat antworten Zitat
Benutzerbild von rawsoul
rawsoul

Registriert seit: 29. Okt 2006
Ort: Düsseldorf
249 Beiträge
 
Delphi 2005 Personal
 
#5

Re: Bezierkurven

  Alt 26. Dez 2006, 15:30
wow, super!

vielen dank für die hilfe! jetzt muss ich nur noch versuchen, nachzuvollziehen, wie du die formel umgeschrieben hast...

frohes fest noch!
Frank Dumont
  Mit Zitat antworten Zitat
Ratte

Registriert seit: 12. Dez 2003
Ort: Erfurt
345 Beiträge
 
Delphi 2005 Personal
 
#6

Re: Bezierkurven

  Alt 26. Dez 2006, 15:45
i/1000 ist das t, und dann halt die Formel einmal für den x- und einmal für den y-Anteil.
Schiffsratte der U.S.S. Delphipraxis, Laderaum 4538
BUSH:= TTerminator.create;
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#7

Re: Bezierkurven

  Alt 26. Dez 2006, 17:38
Béziers werden normalerweise per Casteljau-Algorithmus gezeichnet, wodurch sie beliebig genau dargestellt werden können. Aber auch bei der Parameterfunktion könntest du adaptiv vorgehen, d.h. die Schrittweite von t dort verringern, wo sonst die Abstände zu groß und die Kurve eckig wird. Die dritte Möglichkeit wäre dann noch die GDI+-API, in der eine Bézierfunktion schon enthalten ist. Eine dieser Möglichkeiten solltest du aber auf jeden Fall implementieren, sonst wird das Ergebnis ziemlich hässlich werden.
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Ratte

Registriert seit: 12. Dez 2003
Ort: Erfurt
345 Beiträge
 
Delphi 2005 Personal
 
#8

Re: Bezierkurven

  Alt 26. Dez 2006, 18:05
hast du natürlich recht. Das Beispiel hatte ich ja auch nur schnell zusammengehackt und von dem anderen algorithmus hab ich keine Ahnung, während das hab ich sofort kapiert.
ich würde 1/2x(Abstand aller Punkte) als genauigkeit nehmen. Ist zwar zuviel, reicht aber folglich auf jeden Fall.
Schiffsratte der U.S.S. Delphipraxis, Laderaum 4538
BUSH:= TTerminator.create;
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#9

Re: Bezierkurven

  Alt 27. Dez 2006, 08:51
In meinem Progrämmchen RiB habe ich den De Casteljau Algo recht flott implementiert. Sollte sich imho ganz gut daraus übernehmen lassen.

\\edith: Hier mal die wichtige Funktion
Delphi-Quellcode:

function BezierPoint(pt: TBezierSet; t: Double): TFloatPoint;
var
  t0, t1, t2, t3: Double;
  oneMt, tp2, oneMtp2: Double;
begin
  oneMt := 1-t;
  tp2 := sqr(t);
  oneMtp2 := sqr(oneMt);

  t0 := oneMtp2*oneMt;
  t1 := 3*t*oneMtp2;
  t2 := 3*tp2*oneMt;
  t3 := tp2*t;

  result.x := t0 * pt[0].x +
              t1 * pt[1].x +
              t2 * pt[2].x +
              t3 * pt[3].x;

  result.y := t0 * pt[0].y +
              t1 * pt[1].y +
              t2 * pt[2].y +
              t3 * pt[3].y;
end;
TBezierSet ist ein array[0..3] of TFloatPoint, wobei TFloatPoint ein record mit x,youble ist.
In pt werden hier die 4 Kontrollpunkte der Kurve übergeben, und mit t (0..1) "wandert" man über die Kurve. Um das zu zeichnen muss man diese Funktion also nur in einer Schleife über t aufrufen, und die zurückgelieferten Punkte mit LineTo verbinden. Die Schrittgröße von t bestimmt somit die Genauigkeit (Eckigkeit) des Ergebnisses, und damit auch den Performancehunger

\\edith2: *hust* naja, der De Casteljau isses ja garnicht so richtig. Viel mehr eine günstig zerlegte Variante der o.g. Formel. Wie viel schneller De Castelljau im Vergleich dazu ist, weiss ich leider nicht. Aber mir hat die Funktion zumindest bisher immer brav Beziér Kurven geliefert ^^

\\edit3: Eigentlich kann man mit Beziér Kurven über mehr als nur 4 Punkte annähern, nämlich beliebig vielen. Der Aufwand dafür ist, wenn ich mich recht erinnere, allerdings O(n²), und mit Algo nach De Casteljau O(n*log(n)).
Man wählt jedoch oft die Darstellung durch 4 Kontrollpunkte, da sich damit die lokale Kontrolle in der Kurve deutlich verbessert, und stückelt mehrere 4-Punkt Kurven zu einer komplexeren zusammen, wobei der jeweils 2. und 3. Kontrollpunkt die Tangente in dem Anfangs- und Endpunkt erzeugt. Dadurch kann man auch bei gestückelten Kurven recht einfach weiche Übergänge erzielen.
Wenn du aber nun tatsächlich Kurven über eine variable Anzahl von Kontrollpunkten möchtest, lohnt es sich sicher De Casteljau i.e.S. implementieren, und keine auf 4 Punkte spezialisierte Form. Dazu gibt es massig, und auch gute Infos im Netz (z.B. Wikipedia ist echt brauchbar in dem Punkt).
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#10

Re: Bezierkurven

  Alt 27. Dez 2006, 13:06
Hallo,

für eine kubische Bezier-Kurve könnte man auch Delphi-Referenz durchsuchenTCanvas.PolyBezier nutzen.

Gruß Hawkeye
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 22:54 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