Autor Beitrag
mtin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 177

Win XP SP2
BDS2006 Enterprise
BeitragVerfasst: Mo 02.01.06 01:41 
also, weiß jetzt nicht genau ob ich mit Raytracing überhaupt richtig liege, vielleicht such ich ja sogar nachm falschen, aber egal...

[url=imageshack.us]user defined image[/URL]

wir haben hier eine Lustige Tomate (ich weiß ich bin ein Paint-Gott :D )
die in einem Kreisrunden Raum steht...in dem Raum steht noch ein großer Schrank oder sowas,
auf jeden Fall möchte ich jetzt irgendwie herausfinden,
welche Raumwände die Tomate (oder was auch immer) sehen kann (grün umrandet)
und welche nicht(blau umrandet)....

gibts da irgendwie etwas einfaches, meine einzige Überlegung wäre einfach von jedem Punkt des Kreises aus eine (gedachte) linie zur Tomate zu ziehen und überprüfen, ob diese irgendetwas schneidet bevor sie bei der tomate ist, wenn ja-->nicht sichtbar ( der Punkt auf dem Kreis)

aber ich glaub diese Methode ist mehr als langsam...vielleicht kann mir ja jemand helfen (und mir sagen ob ich mit Raytracing hier richtig liege??)
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mo 02.01.06 02:22 
Man verwendet für das häufig einen Z-Buffer. Wie der genau funktioniert wird auf Wikipedia sehr detailiert beschrieben. Im Prinzip wird immer das gesamte Bild berechnet aber nur die Stellen angezeigt, die am nähesten zur Kamera sind (oder genauer die kleinste Tiefenkoordinate besitzt). Um das zu realisieren merkt sich der Renderer die Tiefenkoordinate von jedem Pixel.
Vorteil: Schnell optisch sehr gute Resultate. Beliebige Schnitte von Körpern sind möglich.
Nachteil: Man kann also am Schluss nicht genau sagen, wo der Sichtbarkeitsbereich oder wo sich zwei Körper schneiden. Man weiss es nur bis zur Auflösung des Bildes.
In deinem 2D-Polaren-Fall geht das alles auch: Du zeichnest die Umgebung einfach in Polarkoordinaten und die Tiefenkoordinate schreibst du in deinen Distanzbuffer. (Falls du keine sich schneidenden Objekte hast kannst du's sogar recht einfach kontinuierlich rechnen und ein exaktes Resultat erhalten)
mtin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 177

Win XP SP2
BDS2006 Enterprise
BeitragVerfasst: Mo 02.01.06 16:03 
puh, also das klingt ja erstmal sehr kompliziert!!

soweit ich das Verstanden habe, gehe ich jeden Pixel des TImage durch und speichere für jeden eine Art "Entfernungswert" zur "Tomate"...und dann muss ich doch aber trotzdem wieder von dem Standpunkt der Tomate sozusagen Strahlen ausgehen lassen um dann das nächste Objekt zu finden...oder?

Also alles was ich eigentlich machen will, ist in diesem Timage in dem die Formen gezeichnet sind die sichtbaren stücken z.b. grün färben und die unsichtbaren blau...und da kann ich mir ehrlich gesagt nicht vorstellen das das mit dem Z-Buffer schneller geht als einfach nur Strahlen auszusenden...zumindest soweit ich das Verstanden habe :?
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mo 02.01.06 16:54 
Können sich deine 2D-Objekte schneiden oder ist dieser Fall ausgeschlossen?
mtin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 177

Win XP SP2
BDS2006 Enterprise
BeitragVerfasst: Mo 02.01.06 17:13 
nein, das ist ausgeschlossen!

allerdings sind die auch nicht rund, das hab ich nur in Paint schnell gemalt, es ist ein großes Vieleck in dem n paar kleinere Vielecke sind! (die sind auch nicht unbedingt ausgefüllt wie in meinem Paint bild)
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mo 02.01.06 18:53 
Und geht des darum herauszufinden, welches Objekt die Tomate sieht oder nur, ob sie die Wand sieht?
mtin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 177

Win XP SP2
BDS2006 Enterprise
BeitragVerfasst: Mo 02.01.06 18:55 
nunja, so wie ich in 2 posts vorher beschrieben habe geht es einfach nur darum, die Teile die von der Tomate :D sichtbar sind mit einer anderen Farbe einzufärben... also schon eher was sie alles sieht! also nicht nur die Wand, sondern auch die ihr zugewandte Seite der inneren Vielecke will ich dann so kennzeichnen!
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mo 02.01.06 19:05 
Naja, wenn es nur um die Wand ginge wäre es nämlich viel einfacher (siehe Anhang). Wenn man die Objekte selbst auch noch unterscheiden muss, wird's etwas komplizierter.

Die Frage ist eben, ob es dir reicht wenn du nur alle 5° oder so weisst welches Objekt die Tomate sieht z.B.:

0°=>Wand
5°=> Wand
10°=>Objekt1
15°=>Wand
...
bis 360°

Was die Tomate bei 2.5° sieht, weisst du dann nicht. Eine kontinuierliche Rechnung geht nicht ohne weiteres. Da gibt es dann ziemlich schnell ziemlich mühsame Fälle...
Wofür brauchst du es genau? Wie performant muss das ganze sein? Ich hoffe, dass ich deine Frage dann beantworten kann, wenn ich das alles weiss ;)
Einloggen, um Attachments anzusehen!
mtin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 177

Win XP SP2
BDS2006 Enterprise
BeitragVerfasst: Mo 02.01.06 19:12 
echt nett das du dir sone Mühe machst ;)

also ich wollte mich einfach mal einarbeiten, will irgendwann mal nen kleines Spielchen schreiben aber jetzt in dem Test geht es nur darum, sozusagen die Schattigen Wand/Objektstücken anders einzufärben als den Rest!
Die Geschwindigkeit ist (fast) egal, also ich will keine 30 fps sondern wäre froh wenns in nen paar Sekunden fertig wäre, länger ist auch nicht unbedingt das Problem...

sollte ich vielleicht einfach versuchen 360 Geradengleichungen aufzustellen und dann 360 Geraden "laufen" lassen und ihren ersten "aufprall" mit einer schwarzen linie dann anders einfärben?
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mo 02.01.06 19:23 
Sagen wir mal die Szene sieht so aus. Es gibt 3 Objekte (Kasten) und eine Tomate:

     2222222
     2     2
     2222222
            333333
            3    3
       T    333333
1111
1  1
1111

Du projizierst die Endpunkte aller Linien auf den Einheitskreis um die Tomate. Du erhältst dann ein Bild, welches etwa so aussieht:
|--------111111111----2222222222333333333---------------------|

Das ist das Bild der Tomate. Jetzt musst du noch einen Z-Buffer für dieses Bild implementieren, dann hast du die Lösung. Schnittpunkte musst du keine berechnen.

PS: Die Projektion geht ganz einfach mit der Funktion ArcTan2 der Unit Math. Aus X- und Y-Koordinate erhältst du dann einen Winkel.
mtin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 177

Win XP SP2
BDS2006 Enterprise
BeitragVerfasst: Di 03.01.06 01:51 
also, ehrlich gesagt versteh ich das auch nicht, das einzige was ich über die Formen weiß sind ihre eckpunkte (x- und y- Koordinaten) und weiß nicht was du mit der Projektion meinst!

und ich glaube ich bräuchte doch jeden Pixel, also so wie auf deinem Bild das ist ziemlich genau das was ich erreichen will, es muss nicht nur die Wand sein (bzw. wär sogar besser mit der Fläche)

hab nochmal ein Bild mit Paint gezeichnet, alles was ich weiß sind die Eckkoordinaten, und ich hätte gerne so eine schöne rote Fläche^^
[url=imageshack.us]user defined image[/URL]
(die schwarzen linien sind nur für mich um zu sehen was ich ausfüllen muss)

eine weiter Überlegung wäre das ganze in Dreiecke einzuteilen und zu überprüfen in welche Dreiecken ein Körper ist und in welchen nicht, allerdings müsste ich dann zunächst für jede Gerade eine Geradengleichung aufstellen und DAS wird dann echt kompliziert :/

Einen graphischen Ansatz hab ich jetzt mehr oder weniger hinbekommen, aber da ich da mit dem Image arbeite (Canvas.Pixels[x,y] usw.) ist das viel zu ungenau, je nächer ich mich der horizontalen Achse nähere desto vermehrt treten solche Muster auf und die Fläche ist nicht mehr gefüllt!
Bei der Methode geh ich einfach jeden Einzelnen Pixel des Bildes durch, und wenn er Schwarz ist, so zeichne ich eine Grüne Linie von meinem Standpunkt zu diesem Schwarzen Pixel. Falls mir jedoch "auf dem weg" noch ein schwarzer Pixel begegnet, so höre ich damit auf....

Dieses Bild wurde mit meinem jetzigen Programm generiert (diesmal kein Paint ;) )
[url=imageshack.us]user defined image[/URL]

ich hoff mal ich nerv dich nicht zu sehr....
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Di 03.01.06 13:47 
Im Grunde muss man sich (wenn ich mir das jetzt richtig überlegt habe) nur die Anfangs- und Endpunkte projizieren, in eine Liste schreiben, sortieren und danach die Intervalle in der Liste durchgehen und der richtigen Linie zuordnen (-> mittels Z-Buffer. Hier reicht es, wenn man pro Intervall ein Z-Wert und die dazugehörige Linie kennt).
Ich kann das jetzt schlecht so erklären, aber wenn ich etwas Zeit finde, werde ich das mal versuchen zu implementieren.

Der Flaschenhals (langsamste Stelle im Code) der ganzen Sache wäre dann die Sortierung.
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Di 03.01.06 14:02 
man hat dann aber nur eine bedingte genauigkeit, je größer die intervalle, desto ungenauer, werden da im professionellen bereich kleinere intervalle gewählt, oder wird das irgendwie interpoliert ?

ich glaube die idee von mtin war, die koordinaten der tomate und die eckpunkte der quadrate zu verbinden und somit hat man ein dreieck, welches man durch verlängerung an eine wand projezieren kann (würde ich glaube ich mit nem vektor machen) und dann kann man genau sehen, von wo bis wo die wand nicht sichtbar ist.


Zuletzt bearbeitet von F34r0fTh3D4rk am Di 03.01.06 14:05, insgesamt 1-mal bearbeitet
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Di 03.01.06 14:04 
Nein, die Methode, die ich vorhin beschrieben habe rechnet exakt und ist unabhängig von der Auflösung. Dafür hat der Algorithmus die Komplexität O(n^2) statt O(n).

In 3D ist das ganze nicht so ein Problem, da der Z-Buffer genauso gross ist wie das sichtbare Bild. Für jeden Pixel hast du einen z-Wert. Hier ist's aber ein bisschen anders: Was wir schlussendlich darstellen wollen ist aber nicht das Bild, welches die Tomate sieht, sondern die ganze 2D-Karte. Die Tomate sieht nämlich nur 1D (siehe oben).

user profile iconF34r0fTh3D4rk hat folgendes geschrieben:
ich glaube die idee von mtin war, die koordinaten der tomate und die eckpunkte der quadrate zu verbinden und somit hat man ein dreieck, welches man durch verlängerung an eine wand projezieren kann (würde ich glaube ich mit nem vektor machen) und dann kann man genau sehen, von wo bis wo die wand nicht sichtbar ist.

So ungefähr funktioniert auch meine Idee. Jedoch projiziere ich die Eckpunkte der Dreiecke nicht auf die Wand sondern allesamt auf den Einheitskreis um die Tomate. Wenn ich alle Eckpunkte auf den Einheitskreis projiziere, habe ich schlussendlich viele Punkte, die diesen Einheitskreis in kleine Intervalle unterteilen. Die Intervalle gilt es nun dem Linienstück zuzuordnen, welches am nächsten zur Tomate ist (geht mit einem z-Buffer-Wert pro Intervall). Das ist alles.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mi 04.01.06 01:40 
So, hab das jetzt mal programmiert. Der Code liefert eine Liste der sichtbaren Liniensegmente und zu jedem Liniensegment einen Pointer auf die Originallinie. Auf dem Bild sieht es manchmal aus, als ob die Strahlen durch die Ecken gehen würden, das liegt aber nur daran, dass die schwarzen Linien sehr dick gezeichnet sind. Bei der Berechnung sind die Linien nämlich unendlich dünn behandelt.

Berechnungszeit ca. 2ms auf meinem 2GHz-Laptop.

Anmerkungen:
- Auf der Form ist nur ein TImage (Image1).
- OnCreate von Form1 muss mit FormCreate verbunden sein.

Den Code müsste man noch etwas aufräumen und Spezialfälle, die evtl. ein "Division durch Null" auslösen, berücksichtigen.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
unit Unit1;
 
interface  
 
uses  
  Windows, Graphics, Forms, StdCtrls, Classes, Controls, ExtCtrls, SysUtils;
 
type  
  TPointPair = array[0..1of TPoint;  
  PPointPair = ^TPointPair;  
  TVisPair = record  
    W: Extended;  
    Flag: Boolean;  
    Line: PPointPair;  
  end;  
  TInterval = record  
    FromW, ToW: Extended;  
    Line: PPointPair;  
    LineSegment: TPointPair;  
  end;  

  TForm1 = class(TForm)  
    Image1: TImage;
    procedure FormCreate(Sender: TObject);  
    procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;  
      Shift: TShiftState; X, Y: Integer);  
  private  
    { Private declarations }  
  public  
    { Public declarations }  
    Lines: array of TPointPair;  
    procedure Redraw;  
    procedure DefLine(X1, Y1, X2, Y2: Integer);  
  end;  

var  
  Form1: TForm1;  

implementation  

uses Math, Contnrs;  
 
{$R *.dfm}  
 
procedure TForm1.DefLine(X1, Y1, X2, Y2: Integer);  
var  
 IndL: Integer;  
begin  
  IndL := Length(Lines);  
  SetLength(Lines, IndL+1);  
  Lines[IndL][0] := Point(X1,Y1);  
  Lines[IndL][1] := Point(X2,Y2);  
end;  
 
procedure TForm1.FormCreate(Sender: TObject);  
begin  
  DefLine(240,42,397,306);  DefLine(397,306,23,345);  DefLine(23,345,240,42);
  DefLine(147,233,194,297); DefLine(194,297,207,214); DefLine(207,214,147,233);
  DefLine(243,155,269,238); DefLine(269,238,292,179); DefLine(292,179,243,155);
  DefLine(307,281,314,260); DefLine(314,260,327,283); DefLine(327,283,307,281);
  Redraw;
end;

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
 Visible: array of TVisPair;
 Intervals: array of TInterval;
 TempVisible: TVisPair;  
 I, J, Ind, Index: Integer;  
 Min, CurrW, LastW, FirstW: Extended;  
 Init: Boolean;  
 LList: TList;
 TempLine: Pointer;
function ProcessList(W: Extended; LList: TList): Integer;
var
 D, MinD: Extended;
 K, L: Integer;
 P1, P2: TPoint;
begin
  MinD := infinite;  
  L := 0;  
  for K := 0 to LList.Count-1 do
  begin  
   P1 := PPointPair(LList[K])^[0];  
   P2 := PPointPair(LList[K])^[1];  
   D := ((P2.Y-Y)*(P1.X-X)-(P2.X-X)*(P1.Y-Y))/(cos(W)*(P2.Y-P1.Y)-sin(W)*(P2.X-P1.X));  
   if D < MinD then  
   begin  
    MinD := D;  
    L := K;  
   end;  
  end;  
  Result := L;
end;  
procedure ProcessLine(IndL: integer);
var  
 W1, W2, W: Extended;  
 IndV: Integer;  
begin  
  W1 := ArcTan2(Lines[IndL][0].Y-Y,Lines[IndL][0].X-X);  
  W2 := ArcTan2(Lines[IndL][1].Y-Y,Lines[IndL][1].X-X);  
  if W1=W2 then  
   exit;
  IndV := Length(Visible);
  SetLength(Visible, IndV+2);  
  if (abs(W1-W2)>pi) xor (W1>W2) then  
  begin  
   W := W1;
   W1 := W2;
   W2 := W;
  end;
  if abs(W1-W2)>pi then
   LList.Add(@Lines[IndL]);
  Visible[IndV].W := W1;
  Visible[IndV].Flag := True;
  Visible[IndV].Line := @Lines[IndL];
  Visible[IndV+1].W := W2;
  Visible[IndV+1].Flag := False;
  Visible[IndV+1].Line := @Lines[IndL];
end;
procedure CalcLineSegment(var Interval: TInterval);  
var  
 P1, P2: TPoint;  
 rx, ry, I1, I2: Extended;  
begin  
  P1 := Interval.Line[0];  
  P2 := Interval.Line[1];  
  SinCos(Interval.FromW, ry, rx);  
  I1 := (rx*(P2.y-Y)-ry*(P2.x-X))/(rx*(P2.y-P1.y)-ry*(P2.x-P1.x));  
  SinCos(Interval.ToW, ry, rx);  
  I2 := (rx*(P2.y-Y)-ry*(P2.x-X))/(rx*(P2.y-P1.y)-ry*(P2.x-P1.x));  
  Interval.LineSegment[0] := Point(Round(I1*P1.X+(1-I1)*P2.X),Round(I1*P1.Y+(1-I1)*P2.Y));  
  Interval.LineSegment[1] := Point(Round(I2*P1.X+(1-I2)*P2.X),Round(I2*P1.Y+(1-I2)*P2.Y));  
end;
begin
  if Length(Lines) = 0 then
   exit;  
  Image1.Picture := nil;  
  LList := TList.Create;
  try
   for I := 0 to Length(Lines)-1 do  
    ProcessLine(I);  
   for I := 0 to Length(Visible)-1 do
   begin  
    Min := Visible[I].W;
    Ind := I;  
    for J := I+1 to Length(Visible)-1 do  
     if Visible[J].W<Min then  
     begin  
      Min := Visible[J].W;  
      Ind := J;  
     end;  
    if Ind <> I then  
    begin  
      TempVisible := Visible[I];
      Visible[I] := Visible[Ind];
      Visible[Ind] := TempVisible;
    end;  
   end;  
   I := 0;  
   LastW := 0;  
   FirstW := 0;  
   Init := True;  
   repeat  
     CurrW := Visible[I].W;  
     if Init then  
     begin  
      Init := False;  
      FirstW := CurrW;  
     end else  
     begin  
      if LList.Count > 0 then
      begin
       Index := Length(Intervals);
       TempLine := LList[ProcessList((LastW+CurrW)/2, LList)];
       if (Index > 0and (Intervals[Index-1].Line = TempLine) and
          (Intervals[Index-1].ToW = LastW) then
         Intervals[Index-1].ToW := CurrW
       else begin
        SetLength(Intervals, Index+1);
        Intervals[Index].FromW := LastW;
        Intervals[Index].ToW := CurrW;
        Intervals[Index].Line := TempLine;
       end;
      end;
     end;
     repeat
      if Visible[I].Flag then
       LList.Add(Pointer(Visible[I].Line)) else
       LList.Delete(LList.IndexOf(Pointer(Visible[I].Line)));
      inc(I);
     until (I=length(Visible)) or (Visible[I].W <> CurrW);
     if I=length(Visible) then
      break;
     LastW := CurrW;
   until false;
   if not Init and (LList.Count > 0then
   begin
    Index := Length(Intervals);
    TempLine := LList[ProcessList((FirstW+2*pi+CurrW)/2, LList)];
    if (Index > 0and (Intervals[Index-1].Line = TempLine) and
       (Intervals[Index-1].ToW = CurrW) then
     Intervals[Index-1].ToW := FirstW
    else begin
     SetLength(Intervals, Index+1);
     Intervals[Index].FromW := CurrW;
     Intervals[Index].ToW := FirstW;
     Intervals[Index].Line := TempLine;
    end;
   end;
   Index := Length(Intervals);
   if (Index > 0and (Intervals[0].Line = Intervals[Index-1].Line) and
      (Intervals[0].FromW = Intervals[Index-1].ToW) then
   begin
    Intervals[0].FromW := Intervals[Index-1].FromW;
    SetLength(Intervals, Index-1);
   end;
   Image1.Canvas.Pen.Width := 1;
   Image1.Canvas.Brush.Color := clRed;
   Image1.Canvas.Pen.Color := clBlack;
   for I := 0 to length(Intervals)-1 do  
   begin  
    CalcLineSegment(Intervals[I]);  
    Image1.Canvas.Polygon([Point(X,Y),  
                           Point(Intervals[I].LineSegment[0].X, Intervals[I].LineSegment[0].Y),  
                           Point(Intervals[I].LineSegment[1].X, Intervals[I].LineSegment[1].Y)]);  
   end;  
  finally  
   LList.Free;  
  end;  
  Redraw;  
end;  

procedure TForm1.Redraw;  
var  
 I: Integer;  
begin  
  Image1.Canvas.Pen.Color := clBlack;  
  Image1.Canvas.Pen.Width := 3;  
  for I := 0 to Length(Lines)-1 do  
  begin  
    with Lines[I][0do  
     Image1.Canvas.MoveTo(X,Y);  
    with Lines[I][1do  
     Image1.Canvas.LineTo(X,Y);  
  end;  
end;  
end.


//Edit: Code optimiert
Einloggen, um Attachments anzusehen!


Zuletzt bearbeitet von delfiphan am Mi 04.01.06 21:25, insgesamt 1-mal bearbeitet
mtin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 177

Win XP SP2
BDS2006 Enterprise
BeitragVerfasst: Mi 04.01.06 18:37 
das is mir echt nich klar wie man sowas mal eben aus dem Ärmel schütten kann :shock:
ist echt perfekt, wahnsinnig schnell.....nur eben leicht kompliziert...

das ist aber genau das was ich mir gedacht hab, hab mir mal die kanten der Polygone einzeichnen lassen, das sind ja genau die mit jeder ecke verbunden...nur eben schaffst du das irgendwie die zu verlängern und auf eine der außenseiten zu projizieren...

egal mehr als Danke und ich werds mal versuchen zu verstehen :D
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Mi 04.01.06 19:10 
brauchst dich nicht zu wundern, bei delfiphan hab ich mir das schon abgewöhnt ^^ ich würde es auf jedenfall nicht hinbekommen eine physikengine zu schreiben ;)
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mi 04.01.06 21:29 
user profile iconmtin hat folgendes geschrieben:
das ist aber genau das was ich mir gedacht hab, hab mir mal die kanten der Polygone einzeichnen lassen, das sind ja genau die mit jeder ecke verbunden...nur eben schaffst du das irgendwie die zu verlängern und auf eine der außenseiten zu projizieren...

Du hast recht. Es werden mehr Dreiecke produziert als eigentlich nötig. Ich habe den oberen Code nun ausgebessert, sodass unnötige Trennungen in Dreiecken vermieden werden. Der Algorithmus ist derselbe. Aber statt blind neue Dreiecke hinzuzufügen wird zuerst versucht ein vorhandenes Dreieck auszuweiten.
Einloggen, um Attachments anzusehen!
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: So 13.05.07 15:51 
Der Code ist nicht grad leichteste Kost ;)

Ich versuch das grad nachzuvollziehen, also die Linien (bzw Strecken) werden auf einen Einheitskreis projeziert ? (der kreis befindet sich an der position des betrachters und hat den radius 1 ?) dabei werden sich überlappende elemente zusammengefasst, sodass die lücken den bereich darstellen, der sichtbar ist. dann wird an den grenzen eine gedachte Linie gezogen, die dann zusammen mit dem ?schnitt? der wände das polygon ergibt, welches gezeichnet wird?

also so ganz verstehe ich das nicht, wie genau funktioniert die projektion und wie geht das dann weiter ?


mfg
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Mi 16.05.07 11:22 
wie kann ich den algorithmus vereinfachen, dass ich ihn für ein raster benutzen kann ? dabei möchte ich aber die nicht sichtbaren teile schwarz färben. aber nicht so, dass ich die einzelne felder färbe. nicht so:

freethings4u.qsh.sk/wp-in/images/cs2d.jpg

sondern so wie in den bisherigen beispielen.

mfg