Autor Beitrag
liquid air
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 76



BeitragVerfasst: Do 12.02.09 22:30 
Schönen guten Abend wünsch ich allerseits :)

Ich hab ein Problem und hoffe dass ihr mir helfen könnt:
Übungsweise wollte ich einen dreidimensionalen Würfel berechnen. Die Punkte sind Vektoren; Jeder Punkt hat zudem
einen winkel alpha und beta für die auslenkung in x1-x3 bzw x1-x2 ebene,
ein da und db für den abstand zum nullpunkt in der jeweiligen ebene
und ein d für den gesamt-Abstand zum nullpunkt (bzgl. des 3d-Raumes also)

Die Idee ist natürlich, dass ich durch Buttondruck alpha und beta für alle punkte gleichzeitig im gleichen Maß verändern kann, sodass sich der Würfel im Endeffekt dreht.

Das konkrete Problem sieht jetzt so aus:
a) der Würfel sollte später dargestellt werden, indem ich die 8 entsprechenden eckpunkte mit einer polyline verbinde. Leider funktioniert die Code-Zeile
ausblenden Delphi-Quelltext
1:
tpoints[i] := Point(xx, yy);					

absolut nicht...(der komplette Quellcode folgt natürlich noch, für den kontext.) Was mache ich falsch? o_O
b) da das mit dem polyline eben noch nicht geht, hab ich das momentan so gelöst, dass ich die punkte einfach grösser mal wenn se weiter vorne sind und kleiner wenn se hinten sind...
bisher sieht das aber so aus, als ob die punkte nicht richtig berechnet werden würden...manche kreise sind unterschiedlich gross obwohl sie in der selben ebene sein sollten.
und der würfel im gesamten wird auch verzerrt...ich bin mir nicht sicher ob das so sein sollte ^^
hab ich da irgendwo einen denkfehler drin?

Da das ganze für mich nur eine freiwillige Übung ist, die ich spontan angefangen hab, is das ganze nicht sooo regelgerecht codiert&formatiert...verzeiht mir also wenns etwas billig aussieht ^^"

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:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
unit Unit1;

interface

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

type
  point = record
    x: integer;
    y: integer;
    z: integer;
    d: double;
    da: double;
    db: double;
    alpha: double;
    beta: double;
  end;

type
  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    Timer1: TTimer;
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Button3: TButton;
    Button4: TButton;
    Label3: TLabel;
    Label4: TLabel;
    Timer2: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
  private
    { Private-Deklarationen }
    function sinus(angle: Real): Real;
    function cosinus(angle: Real): Real;
  public
    { Public-Deklarationen }
    procedure initialize;
    procedure init_points;
    procedure calc;
    procedure draw;

  end;

const
  weit = 500;
  hoch = 500;
  mitte = weit div 2;

var
  Form1: TForm1;
  buffer: TBitmap;
  mWeit, mHoch, anzPoints, change, faktor: integer;
  points: array[0..9] of point;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  initialize;
end;

procedure TForm1.initialize;
begin
  //festlegen der größe von feld, paintbox und buffer für paintbox
  form1.ClientHeight := hoch;
  form1.ClientWidth := weit;
  paintbox1.Width := form1.ClientWidth;
  paintbox1.Height := form1.ClientHeight;
  buffer := TBitmap.Create;
  buffer.Width := paintbox1.Width;
  buffer.Height := paintbox1.Height;
  mWeit := weit div 2;
  mHoch := hoch div 2;
  anzPoints := 0;
  change := 5;    // wie schnell ändert sich winkelmaß
  faktor := 100;     // faktor für größe des würfels
  init_points;
  calc;
  draw;
end;

procedure TForm1.init_points;
var i: integer;
begin
  points[0].x := 0;   // B
  points[0].y := 0;
  points[0].z := 0;

  points[1].x := 0;   // A
  points[1].y := 0;
  points[1].z := 1;

  points[2].x := 0;   // F
  points[2].y := 1;
  points[2].z := 0;

  points[3].x := 0;   // E
  points[3].y := 1;
  points[3].z := 1;

  points[4].x := 1;   // C
  points[4].y := 0;
  points[4].z := 0;

  points[5].x := 1;   // D
  points[5].y := 0;
  points[5].z := 1;

  points[6].x := 1;   // G
  points[6].y := 1;
  points[6].z := 0;

  points[7].x := 1;   // H
  points[7].y := 1;
  points[7].z := 1;

  inc(anzPoints, 8);

  for i := 0 to anzPoints-1 do begin
    //punkte zuschneiden auf das neue maß des würfels
    points[i].x := points[i].x * faktor;
    points[i].y := points[i].y * faktor;
    points[i].z := points[i].z * faktor;

    points[i].d := sqrt(sqr(points[i].x)+sqr(points[i].y)+sqr(points[i].z));

    points[i].da := sqrt(sqr(points[i].x)+sqr(points[i].y));     
    points[i].db := sqrt(sqr(points[i].x)+sqr(points[i].z));   

    if points[i].da <> 0 then begin
      points[i].alpha := (arcsin(points[i].y / points[i].da)) * 180/pi;  
    end;

    if points[i].db <> 0 then begin
      points[i].beta := (arcsin(points[i].z / points[i].db)) * 180/pi;   
    end;
  end;

  timer1.enabled := true;
end;

procedure TForm1.calc;
var i: integer;
begin
  //berechnet für jeden punkt die neuen eigenschaften
  for i := 0 to anzPoints-1 do begin
    points[i].x := trunc(points[i].da*cosinus(points[i].alpha));           
    points[i].y := trunc(points[i].da*sinus(points[i].alpha));     

    points[i].x := trunc(points[i].db*sinus(points[i].beta));
    points[i].z := trunc(points[i].db*cosinus(points[i].beta));     
  end;
end;

procedure TForm1.draw;    //die zeichnen-methode
var i, xx, yy, zz, size: integer;
  tpoints: array[0..7] of tpoint;
begin
  buffer.Canvas.Brush.Color := clWhite;
  buffer.Canvas.Rectangle(0, 0, weit, hoch);      
  buffer.Canvas.Rectangle(mitte-5, mitte-5, mitte+5, mitte+5);
  for i := 0 to anzPoints-1 do begin
    xx := points[i].x;
    yy := points[i].y;
    zz := points[i].z;

    // hier die zeile von oben: was geht da nicht???
    tpoints[i] := Point(xx, yy);  
    // alternativ so; geht aber auch nicht:
    // tpoints[i].X := points[i].x + mitte;
    // tpoints[i].Y := points[i].y + mitte;

    size := trunc(( zz + points[i].d ) / 15 );
    buffer.Canvas.Ellipse
      (mitte + xx - size, mitte + yy - size, mitte + xx + size, mitte + yy + size);
  end;

  paintbox1.Canvas.Draw(0, 0, buffer);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if getasynckeystate (VK_ESCAPE) <0 then close;
  if getasynckeystate (VK_BACK) <0 then exit;
  if getasynckeystate (VK_LEFT) <0 then button3.Click;
  if getasynckeystate (VK_RIGHT) <0 then button4.Click;
  if getasynckeystate (VK_UP) <0 then button1.Click;
  if getasynckeystate (VK_DOWN) <0 then button2.Click;

  calc;
  draw;
end;

//sin bzw cos für für rad <-> deg umrechnung
function TForm1.sinus(angle: Real): Real;
begin
  result := sin(Pi*angle/180);
end;

function TForm1.cosinus(angle: Real): Real;
begin
  result := cos(Pi*angle/180);
end;

//die methoden für das ändern des winkelmaßes
procedure TForm1.Button1Click(Sender: TObject);
var i: integer;
begin
  for i := 0 to (anzPoints-1) do begin
    if (points[i].alpha-change) < 0  then
      points[i].alpha := 360-change
    else
      points[i].alpha := points[i].alpha - change;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var i: integer;
begin
  for i := 0 to (anzPoints-1) do begin
    if (points[i].alpha+change) > 360  then
      points[i].alpha := change
    else
      points[i].alpha := points[i].alpha + change;
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
var i: integer;
begin
  for i := 0 to (anzPoints-1) do begin
    if (points[i].beta-change) < 0  then
      points[i].beta := 360-change
    else
      points[i].beta := points[i].beta - change;
  end;
end;

procedure TForm1.Button4Click(Sender: TObject);
var i: integer;
begin
  for i := 0 to (anzPoints-1) do begin
    if (points[i].beta+change) > 360  then
      points[i].beta := change
    else
      points[i].beta := points[i].beta + change;
  end;
end;

procedure TForm1.Timer2Timer(Sender: TObject);
var i: integer;
begin
  {
  for i := 0 to anzPoints-1 do begin
     showmessage(inttostr(i) + '>    a: ' + inttostr(trunc(points[i].alpha)) + '      b: ' +
       inttostr(trunc(points[i].y)));
  end;
  }


  timer2.Enabled := false;
end;

end.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 13.02.09 00:55 
user profile iconliquid air hat folgendes geschrieben Zum zitierten Posting springen:
Leider funktioniert die Code-Zeile
ausblenden Delphi-Quelltext
1:
tpoints[i] := Point(xx, yy);					

absolut nicht...
Sehr präzise Fehlerbeschreibung. Lässt es sich nicht kompilieren, tritt eine Exception beim Ausführen auf, funktioniert es nicht wie du dachtest, ...?
liquid air Threadstarter
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 76



BeitragVerfasst: Fr 13.02.09 16:08 
Oh tschuldigung, ich dachte das wär klar...Weil der Fehler wirklich so scheint als ob er n ganz ganz dummer wär wo ich einfach ne Syntax falsch verstanden hab oder so...

Also, es lässt sich nicht compillieren. Der Curser bliebt hinter dem 'xx,' stehn und sagt was von wegen ) erwartet aber ; gefunden...Und zieht dann natürlich 3-4 andere Fehler hinter sich her von wegen 'operator / semikolon fehlt, deklaration erwartet...blabla.Das is doch normalerweise n Syntaxfehler? Und, wenn ich die Zeile auskommentiere, startet das programm ja. Von daher...
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 13.02.09 16:26 
Aaarrgh...
Ich hatte mich schon gewundert bis mir ein Verdacht kam und ich zurück ganz hochgescrollt habe... :autsch:

user profile iconliquid air hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
type
  point = record
    x: integer;
    y: integer;
    z: integer;
    d: double;
    da: double;
    db: double;
    alpha: double;
    beta: double;
  end;

tpoints[i] := Point(xx, yy);
Dein Typ Point ist "näher" deklariert, nämlich in der selben Datei, deshalb denkt Delphi du meinst den Typ mit Point, nicht die Funktion...

Typbezeichnungen sollten immer mit T anfangen. Dann gibt es da auch keine Missverständnisse. Und sie sollten eben nicht genauso heißen wie vorhandene Bezeichner, deshalb ist es sinnvoller, etwas zu wählen, was zu dem Programm passt. T3DPoint oder sowas z.B., jedenfalls nix so einfaches, was es schon gibt.

Du kannst ja einfach den gewünschten Namen vorher versuchen zu verwenden. Wenn das ein undefinierter Bezeichner ist, dann gibts den zumindest in den eingebundenen Standardunits nicht. ;-)