AGB  ·  Datenschutz  ·  Impressum  







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

2D-Pixel eines Control3D?

Ein Thema von laube53 · begonnen am 28. Sep 2013 · letzter Beitrag vom 20. Okt 2013
 
laube53

Registriert seit: 10. Feb 2011
Ort: Berlin
10 Beiträge
 
#5

AW: 2D-Pixel eines Control3D?

  Alt 20. Okt 2013, 19:22
Meine Erkenntnisse bis jetzt:
Ich habe begonnen mit einer FireMonkey3D-Demo namens Arrows3D, siehe http://cc.embarcadero.com/item/29148.

Bei einer Projektion vom 3-dimensionalen Raum auf einen Bildschirm kann man sich zwischen einr Parallelprojektion
und einer Zentralprojektion entscheiden.

FireMonkey3D benutzt eine Zentralprojektion: Der Bildpunkt P' von P ist der Schnittpunkt der Gerade OZ mit der
Bildebene E: P' = OZ geschnitten E.

Z ist das Projektionszentrum, bei Firemonkey die (absolute) Position der Camera.

Die Bildebene E ist die Senkrechte zur Camera-Richtung und geht durch den Nullpunkt.
In der Bildebene E legt man einen "Ursprung" VP und zwei Basisvektoren VH (horizontal) und VV (vertikal) fest.
Die Koordinaten des Bildpunkts P' sind dann s und t, wenn der Ortsvektor von P' gleich dem von VP + r*VH + s*VV ist.

Die Umwandlung von P' in Bildschirmpixel geschieht dann anhand einer "Karte":
Sie legt ein reelles Intervall [a,b] für die s-Koordinate und [c,d] für die t-Koordinate fest,
Randpixel pa (linker Rand) und Pd (oberer Rand) und es bzw. es (Pixel pro s-Einheit bzw. Pixel pro t-Einheit).

Sei [XVon, XBis] x [YVon, YBis] x [ZVon, ZBis] der sichtbare Bereich der x- y- und z-Achse.

Das kann man folgendermaßen in Delphi aufschreiben:

type
TKarte = record {Daten zur Transf.von xy-Koordinaten in Pixel}
a,b,c,d :Single; {sichtbares Rechteck}
pa,pd :integer; {Pixel von (a,d) = linke obere Ecke}
es,et :LongInt; {Pixel pro Einheit}
end;

TProjTyp=(parallel,zentral); {Parallel- oder Zentralprojektion }
TProjDaten=record {Proj.ebene: VX = VP+tVH+sVV }
PT:TProjTyp;
VS,VP,VH,VV:TVector3D; {VS: Proj.richtung bzw. -zentrum }
end;

var
Projektion: TProjDaten;
Karte:TKarte;

function XPix(s:Single):Single; {Umrechnung von s,t in Pixel}
begin
with Karte do
XPix:=pa+ex*(s-a);
end;

function YPix(t:Single):Single;
begin
with Karte do
YPix:=pd+ey*(d-t);
end;

procedure normiere(var v:TVector3D);
var t:Single;
begin
t:=sqrt(v.X*v.X+v.Y*v.Y+v.Z*v.Z);
if t<>0 then
begin
v.X:=v.X/t;
v.Y:=v.Y/t;
v.Z:=v.Z/t;
end else
raise Exception.Create('Versuch,Nullvektor zu normieren!');
end;

procedure SetPDC(Camera:TCamera; w,h:Single); {setzt Projektion gemäß Camera}
var
N,V : TVector3D;
PD : TProjDaten;
begin
Karte.a:=XVon*1.25; // ist der tatsächlich in Viewport3D sichtbare Bereich
Karte.b:=XBis*1.25;
Karte.c:=YVon*1.1;
Karte.d:=YBis*1.1;
Karte.pa:=0;
Karte.pd:=0;
Karte.ex:=Round(w/(Karte.b-Karte.a)); //w=Viewport3D1.Width);
Karte.ey:=Round(h/(1*(YBis-YVon))); //h=Viewport3D1.Height);

PD.PT:=zentral;
PD.VS:=Camera.AbsolutePosition; {Projektions-Zentrum Z}

PD.VP.X:=0; {Ursprung des Koordinatensystems der Bildebene}
PD.VP.Y:=0;
PD.VP.Z:=0;

N:=Camera.AbsoluteDirection;
Normiere(N);
V.X:=-N.Y*N.X;
V.Y:=1-N.Y*N.Y;
V.Z:=-N.Y*N.Z;
Normiere(V);
PD.VV:=V;
PD.VH:=N.CrossProduct(V);

Projektion:=PD;
end;

procedure project(x,y,z:Single; var s,t:Single);
var
d,dx,dy:Single;
U1,U2,VH0,VV0:TVector3D;
k:integer;
begin
with Projektion do
begin {Berechnung d.Schnittpunkts}
if PT=zentral then
begin
U1.X:=VS.X-w.X;
U1.Y:=VS.Y-w.Y;
U1.Z:=VS.Z-w.Z;
end else
begin
U1.X:=VS.X; {U1=RichtungsTVector3D}
U1.Y:=VS.Y;
U1.Z:=VS.Z;
end;
U2.X:=w.X-VP.X; {U2=rechte Seite des LGS}
U2.Y:=w.Y-VP.Y;
U2.Z:=w.Z-VP.Z;

VH0:=VH;
VV0:=VV;
normiere(VH0);
normiere(VV0);

d:=det(U1,VH0,VV0); {Determinate}
dx:=det(U1,U2,VV0);
dy:=det(U1,VH0,U2);
if d=0 then
raise Exception.Create('Projektionsgerade parallel zur Ebene! Prozedur abgebrochen')
else begin
s:=dx/d;
t:=dy/d;
end;
end;
end;

Der letzte Schritt (Umrechnung von s,t in Pixel) ist aber noch verbesserungsbedürftig.
WorldToScreen ist da genauer.
Thomas Lauer
  Mit Zitat antworten Zitat
 

 

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 17:05 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