Ausgabe Optimierung

Allgemeine Fragen zu Lasershow Software und Show-Programmierung.
Antworten
Benutzeravatar
equal
Beiträge: 91
Registriert: Di 04 Sep, 2007 12:29 pm
Wohnort: Essen
Kontaktdaten:

Ausgabe Optimierung

Beitrag von equal » Di 01 Jan, 2008 6:52 pm

Hallo Laseristen,

ich beschäftige mich momentan mit der Optimierung von Vektorgrafiken zur Ausgabe mit Easylase. Das Einfügen von zusätzlichen Stützpunkten auf Geraden klappt schon sehr gut. Auch das Wiederholen von Start und Endpunkten funktioniert. Letzteres möchte ich jetzt abhängig von dem Winkelunterschied zwischen zwei aufeinanderfolgenden Geraden gestalten.

stumpfer Winkel -> wenig oder keine Punktwiederholungen
spitzer Winkel -> mehr Punktwiederholungen

Ich habe dazu folgendes Implementiert: Von jeder Gerade wird ein Vektor bestimmt (Differenz der X und Y Anteile des Start und Endpunkt). Mit folgender Formel wird der Winkelunterschied der Vektoren berechnet:

Bild

Dabei ist (X1,Y1) der Vektor der vorherigen und (X2,Y2) der Vektor der aktuellen Gerade. Das Ergebnis der Berechnung ist der Winkelunterschied zwischen beiden Geraden.

Das klappt auch ganz gut, ist aber ein ziemlich Performance kostender Ansatz. Ich habe hier im Forum gelesen, das dieses Problem schon einige Male gelöst wurde. Aber leider steht dort nirgendwo wie. Darum meine Frage: Gibt es einen einfacheren (Performance schonenderen) Lösungsweg?

Gruß und frohes neues Jahr ... Erik

Benutzeravatar
gento
Beiträge: 3973
Registriert: Fr 17 Nov, 2000 12:00 pm
Do you already have Laser-Equipment?: Apollo 4a + 4b , Turbotrack 2 , Minisax +++ G120DT +++ G138DT +++
Raytrack 40 ,CT 6210 , CT 6800 , K12
Pangolin , LDS Dynamics ,Phoenix Premium , LDS 2010 ,LDS 2008 , HE
Gas RGB 2W , 800 mW , ALC60
RGB >1W +++
Wohnort: D / NRW / Hamm

Beitrag von gento » Di 01 Jan, 2008 6:59 pm

Code: Alles auswählen

function Scannerrichtung(X_Start,Y_Start,X_End,Y_End : SmallInt) : Word;         // 12 Uhr = 0 Grad
var
  Dif_Y,Dif_X : SmallInt;
  Dif_N:Double;
  Grad:SmallInt;
begin
  Dif_Y:=Y_End-Y_Start;
  Dif_X:=X_End-X_Start;
  Dif_N:=Sqrt(Dif_Y*Dif_Y+Dif_X*Dif_X);
  Grad:=Round(RadToDeg(ArcSin(Dif_Y/Dif_N)));
  if X_End < X_Start then Grad:=-Grad+180;
  if Y_End < Y_Start then Grad:=Grad+90;
  Result:=Grad;
end;
Ich benutze diese Function um Frames auf Wege zu Optimieren.
Allesdings wenn es auf Speed ankommt, rechne ich ArcSin vorher in ein Array ein. Array[0..3600] sollte reichen.

lg Gento
Bild

Benutzeravatar
equal
Beiträge: 91
Registriert: Di 04 Sep, 2007 12:29 pm
Wohnort: Essen
Kontaktdaten:

Beitrag von equal » Di 01 Jan, 2008 10:00 pm

Hallo Gento,

Dein Lösungsweg ist performanter. Ich habe ihn mal analysiert: Du berechnest zuerst die Länge der beiden Katheten des Dreiecks dessen Hypotenuse die abzubildende Gerade ist (Dif_X und Dif_Y). Dann die Länge der Hypotenuse (Dif_N). Das Verhältnis zwischen Gegenkathete und Hypotenuse ist dann sin(alpha). Da das Ergebnis nur in einem Quadranten eindeutig ist, muss es für negative Steigungen noch angepasst werden.

Da meine Library eh schon die Hypotenuse berechnet (wichtig für die Interpolation), brauch ich nur noch das Verhältnis zur Gegenkathete zu berechnen und für negative Steigungen anpassen. Die Umrechnung in Rad bzw. Grad lass ich weg. Für den Vergleich zweier Geraden reicht auch ein Vergleich der Quotienten ...

Vielen Dank für den Lösungsweg!

(ich hatte schon vermutet das meine Lösung über die Bildung des Skalarprodukts wie mit Kanonen auf Spatzen schiessen ist ...)

Gruß ... Erik

Benutzeravatar
equal
Beiträge: 91
Registriert: Di 04 Sep, 2007 12:29 pm
Wohnort: Essen
Kontaktdaten:

Beitrag von equal » Mi 02 Jan, 2008 1:39 pm

Hallo Gento,

leider kann ich Deine Lösung nicht vollständig nachvollziehen. Hier ein Beispiel für eine Gerade von X1=2048;Y1=2048 nach X2=2048;Y2=2548. Die Gerade geht also senkrecht nach oben in Richtung 12 Uhr.

Dif_X=X2-X1=2048-2048=0
Dif_Y=Y2-Y1=2548-2048=500
Dif_N=SQRT(0*0+500*500)=500
winkel=ArcSin(500/500)*(180/Pi)=90 Grad

Da weder Dif_X noch Dif_Y negativ sind, sind keine Anpassungen vorzunehmen.

Der Kommentar in Deinem Quellcode suggeriert das bei diesem Beispiel das Ergebnis 0 Grad betragen müsste, das Ergebnis beträgt aber 90 Grad.

Verwendest Du ein anderes Koordinatensystem?

Gruß ... Erik

tl
Beiträge: 46
Registriert: So 30 Okt, 2005 1:24 pm
Wohnort: Karlsruhe

Beitrag von tl » Mi 02 Jan, 2008 2:32 pm

Bei mir sieht das so aus:

Code: Alles auswählen

function TLaserLine.NormAngle : extended;
begin
  result := RadToDeg(ArcTan2(self.EndPoint.y - self.StartPoint.y, self.EndPoint.x - self.StartPoint.x));
  if result < 0 then result := result + 360;
end;
0/0 links unten
1/1 oben rechts

Winkel auf 12 Uhr = 0°

Thomas

Benutzeravatar
equal
Beiträge: 91
Registriert: Di 04 Sep, 2007 12:29 pm
Wohnort: Essen
Kontaktdaten:

Beitrag von equal » Do 03 Jan, 2008 9:41 am

Hallo TL,

Deine Lösung mit der Tangens Funktion ist ja - da man die Hypotenuse nicht braucht - noch performanter. Leider habe ich auf Anhieb keine Library mit der arctan2 Funktion gefunden - macht aber nichts. Ich verwende nun diese Lösung (in Pseudocode):

Code: Alles auswählen

xdiff=x2-x1;
ydiff=y2-y1;
if xdiff==0 then
  if ydiff<0 then winkel=180 else winkel=0;
else
  winkel=90-(arctan(ydiff/xdiff)*(180/pi));
  if xdiff<0 then winkel=winkel+180;
end if
Gruß ... Erik

Benutzeravatar
gento
Beiträge: 3973
Registriert: Fr 17 Nov, 2000 12:00 pm
Do you already have Laser-Equipment?: Apollo 4a + 4b , Turbotrack 2 , Minisax +++ G120DT +++ G138DT +++
Raytrack 40 ,CT 6210 , CT 6800 , K12
Pangolin , LDS Dynamics ,Phoenix Premium , LDS 2010 ,LDS 2008 , HE
Gas RGB 2W , 800 mW , ALC60
RGB >1W +++
Wohnort: D / NRW / Hamm

Beitrag von gento » Do 03 Jan, 2008 10:02 am

Die ArcTan2 Löung ist schon genial.
Weil Delphi da selbst die Bereichsprüfungen vornimmt.

Gento
Bild

Benutzeravatar
gento
Beiträge: 3973
Registriert: Fr 17 Nov, 2000 12:00 pm
Do you already have Laser-Equipment?: Apollo 4a + 4b , Turbotrack 2 , Minisax +++ G120DT +++ G138DT +++
Raytrack 40 ,CT 6210 , CT 6800 , K12
Pangolin , LDS Dynamics ,Phoenix Premium , LDS 2010 ,LDS 2008 , HE
Gas RGB 2W , 800 mW , ALC60
RGB >1W +++
Wohnort: D / NRW / Hamm

Beitrag von gento » Do 03 Jan, 2008 11:49 am

Code: Alles auswählen

function ArcTan2(const Y, X: Extended): Extended;
asm
        FLD     Y
        FLD     X
        FPATAN
        FWAIT
end;

Aus der Orginal Delphi Unit.

Der komplette Code der Delphi Unit Math.Pas: http://www.gento.de/Math.rar

Im Klartextcode war der nur in der Delphi Version 7 vorhanden ,ansonsten fertig 'Kompeliert'.

Gento
Bild

Benutzeravatar
equal
Beiträge: 91
Registriert: Di 04 Sep, 2007 12:29 pm
Wohnort: Essen
Kontaktdaten:

Beitrag von equal » Do 03 Jan, 2008 1:05 pm

Da merkt man das ich mir die Opcodes aktueller Prozessoren schon (sehr) lange nicht mehr angeschaut habe. Jaja, immer dieses Hochspracheprogrammieren. Von den Opcodes FTAN und FATAN hatte ich noch Dunkel was in Erinnerung - aber FPTAN und FPATAN sind mir völlig neu.

Offen ist noch - was geschieht wenn X = 0 ist? Müsste eigentlich eine Exception geben. Muss ich mal ausprobieren ...

Danke für den Tipp ...

Gruß ... Erik

tl
Beiträge: 46
Registriert: So 30 Okt, 2005 1:24 pm
Wohnort: Karlsruhe

Beitrag von tl » Do 03 Jan, 2008 3:30 pm


Antworten

Zurück zu „Software & Programmierung“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste