Autor Beitrag
Blackbird
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 54



BeitragVerfasst: Sa 01.03.03 21:55 
Ich versuche schon Stunden lang dieses Problem zu lösen. Dies ist eigentlich ein Teil aus einer Grafikengine (was es zumindest irgendwawnn mal werden soll).
Das Problem and sich hat aber eher mit Delphi zu tun, deshalb poste ich es hier.
Ich habe mal nur das wichtigste rausgenommen und in eine Unit gepackt damit das alles deutlicher wird.

Hier die Unit (Auf der Form braucht ihr ne Listbox und ein Button:

ausblenden volle Höhe 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:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type TVector = packed record
        x,y,z: single;
end;

function vector3f(Px,py,pz: single): TVector;
function vectostr(V: tVector): string;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type PVector = ^Tvector;

var
  Form1: TForm1;
  vertexarray: Array of tvector;
  PointerArray: array of PVector;
implementation

{$R *.dfm}

function vector3f(Px,py,pz: single): TVector;
begin

result.x := PX;
result.y := PY;
result.z := PZ;
end;

function vectostr(V: tVector): string;
begin

result := 'x: ' + floattostrf(V.x,fffixed,10,2);
result := result+ '  y: ' + floattostrf(V.y,fffixed,10,2);
result := result+ '  z: ' + floattostrf(V.z,fffixed,10,2);
end;

procedure TForm1.Button1Click(Sender: TObject);
var i,j: integer;
begin

setlength(Vertexarray,length(VertexArray)+3);
Setlength(PointerArray,length(PointerArray)+3);

VertexArray[high(vertexarray)-2] := vector3f(4,4,4);
VertexArray[high(vertexarray)-1] := vector3f(5,5,5);
VertexArray[high(vertexarray)]   := vector3f(6,6,6);

PointerArray[high(PointerArray)-2] := @Vertexarray[High(Vertexarray)-2];
PointerArray[high(PointerArray)-1] := @Vertexarray[High(Vertexarray)-1];
PointerArray[high(PointerArray)] := @Vertexarray[High(Vertexarray)];

j:=1;
for i:=0 to high(Pointerarray) do
        begin
                Listbox1.items.add(vectostr(Pointerarray[i]^));
                if j mod 3 = 0 then listbox1.Items.Add('');
                inc(j);
        end;

end;

end.


Führt dies einfach mal aus!

Nach dem ersten Mal klicken stimmts noch, aber schon beim zweiten Mal wird der z-Wert im 3. Vektor (PointerArray[3].z) auf Null gesetzt und damit stimmt GAR NIX MEHR!!!

Bitte helft mir....

Moderiert von user profile iconTino: Titel geändert.
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Sa 01.03.03 23:19 
Dein Fehler liegt in diesen 3 Zeilen:
Zitat:
PointerArray[high(PointerArray)-2] := @Vertexarray[High(Vertexarray)-2];
PointerArray[high(PointerArray)-1] := @Vertexarray[High(Vertexarray)-1];
PointerArray[high(PointerArray)] := @Vertexarray[High(Vertexarray)];

Hiermit übergibst du die Speicheradresse der Vertexarray-Elemente an das PointerArray. Wenn du nun aber im nächsten Durchgang SetLength() für Vertexarray aufrufst, und der notwendige Speicherplatz nicht hinten angefügt werden kann, so muss das gesamte Array verschoben werden, womit deine Zeiger nicht mehr an die richtige Stelle zeigen, was normalerweise zu einer Schutzverelzung führen würde. In deinem Beispiel tritt diese nur nicht auf, da der ehemalige Speicher von Vertexarray von etwas anderem belegt wird (z.B. PointerArray).

Die einzige Lösungsmöglichkeit wäre, das PointerArray jedesmal komplett neu aufzubauen.

_________________
Ist Zeit wirklich Geld?
Blackbird Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 54



BeitragVerfasst: So 02.03.03 13:25 
Erst mal danke für die Antwort.
Nun ist es aber so, dass es eigentlich keinen PointerArray gibt. Das Ganze sieht eher so aus(nur das Wichtigste):
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
type TTriangle = packed record
           Vertices: array[0..2] of PVector;
           ...
end;

type T3DObject = class

        TriangleArray: array of TTriangle;
        VertexArray: Array of TVector; 
        ...
end;


Die Pointer in jedem Dreieck zeigen also auf bestimmte Punkte im VertexArray des Objectes, d.h.: ein erneutes Durchlaufen ist nicht wirklich möglich.

Bleiben zwei Alternativen:
1. Die Pointer (vertices) auf das VertexArray austauschen durch normale Integer Werte, die den Index des VertexArrays angeben.

2. Eigene Dynmaische Arrays erstellen (also die herkömliche Weise) um Delphis hauseigene Dynamische Arrays zu umgehen.


Hier gehts um Geschwindigkeit, also welche Möglichkeit ist hier vorzuziehen ?
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: So 02.03.03 16:39 
Blackbird hat folgendes geschrieben:
2. Eigene Dynmaische Arrays erstellen (also die herkömliche Weise) um Delphis hauseigene Dynamische Arrays zu umgehen.

Da triffst du aber auch auf dieselbe Problematik mit dem verschieben des gesamten Arrays:

AAAAAA__BHier ist noch für 2 Einträge Platz, wenn diese gefüllt sind, musst du das gesamte Array an einen Platz verschieben, an dem noch Platz ist.


Zitat:
Hier gehts um Geschwindigkeit, also welche Möglichkeit ist hier vorzuziehen ?

Du könntest herausfinden, wieviele Elemente das Array maximal haben kann und dann die Länge des Arrays auf diesen Wert gleich am Anfang setzen. Danach muss das Array nicht mehr verschoben werden, da genug Platz schon vorhanden ist.
Lieber hast du mehr Speicher reserviert, denn das Verkleinern des Arrays verschieb es nicht.

_________________
Ist Zeit wirklich Geld?