Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Sphärenkoordinaten...


Delete - Do 16.12.04 00:18
Titel: Sphärenkoordinaten...
Hi all...

Ich bin gerade dabei ein bissl OpenGL mit Delphi zu proggen und dafür wollte ich mir meine eigene Sphäre
erschaffen - erstmal brauch ich dafür ja die Koordinaten...

Also hab ich mir folgendes gedacht :
Zuerst berechne ich die Y Koordinaten eines Halbkreises in 2D, von x = 0 bis 2 * r...


Quelltext
1:
2:
3:
4:
5:
6:
          y ---- y
  y     / |      | \
  |   y   |      |   y
  |  /|   |      |   |\
  __________________________________x-Achse
ArrOfY[1] [2]    [3] [4]


und speichere diese y Werte in einem Array.
Dann lasse ich das gleiche nochmal durchlaufen, nur das ich Kreise an der YZ-Achse beschreiben lasse, wobei
der Radius immer dem aktuellen Y-Wert entspricht...

Hier mal der Quellcode...


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:
var                                             //Zur Info : globale Vars...
..
  ArrOfY: Array of Double;
  ArrOfZ: Array of Double;
..
procedure TForm1.bCalcKrClick(Sender: TObject);                               //Berechnung der XY-Werte, funktioniert einwandfrei...
var
  r: Double;          
  i: Integer;           
begin
  r := StrToFloat(eRadius.Text);
  mOutputKr.Lines.Text := '';
  setLength( ArrOfY, (round(r) * 2) + 1 );  //Array setzen...
  for i := 0 to (2 * round(R)) do
      ArrOfY[i] := sqrt( sqr(R) - sqr(R - i) ); //Werte berechnen
  for i := 0 to high(ArrOfY) do  //Ausgeben...
    mOutputKr.Lines.Text := mOutputKr.Lines.Text + createOutput( FloatToStr(ArrOfY[i]), IntToStr(i) )
end;
..
procedure TForm1.bCalcSphClick(Sender: TObject);                    //Berechnung der YZ-Koordinaten
var
  r: Double;           
  y, i, j: Integer;           
begin
  r := StrToFloat(eRadius.Text);
  mOutputSph.Lines.Text := '';
  setLength( ArrOfZ, round(r) * 2 + 1);                              //init länge setzen
  for i := 1 to high(ArrOfZ) do
    begin
      y := round(ArrOfY[i]);
      setLength( ArrOfZ, High(ArrOfZ) + (y * 2) + 1 );               //Länge kontinuierlich erhöhen, da hier wesentlich mehr Einträge kommen...
      for j := round(ArrOfY[i - 1]) to round(ArrOfY[i - 1]) + ((y) * 2do
        ArrOfZ[j] := sqrt( sqr(round(ArrOfY[i - 1])) - sqr(round(ArrOfY[i - 1]) - j) )                     //Berechnen...
    end;
  for i := 0 to high(ArrOfZ) do                                      //Ausgeben..
    mOutputSph.Lines.Text := mOutputSph.Lines.Text + createOutput( FloatToStr(ArrOfZ[i]), IntToStr(i) )
end;


soweit so gut, nur wenn ich jetzt die YZ-Koordinaten berechnen lassen möchte, kommt "invalid floating point operation" , und zwar bei
folgender Zeile :


Delphi-Quelltext
1:
        ArrOfZ[j] := sqrt( sqr(y) - sqr(y - j) )                    


Nun bin ich heute wohl zu Müde, breit oder sonst was, nur ich finde meinen Fehler nicht, die Länge des Arrays ist einwandfrei, ebenso die Berechnung...mein ich doch :o(

Moderiert von user profile iconChristian S.: Code-Tags hinzugefügt


Delete - Do 16.12.04 16:07

Ich hab den Quelltext jetzt nochmal ein Stück überarbeitet, damit ich damit besser arbeiten kann:


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:
var
  y, r, n: Double;
  i, j: Integer;
  arr: Array of Double;
begin
  r := StrToFloat(eR.Text);
  n := StrToFloat(eN.Text);
  mOut.Lines.Text := '';
  setLength(arr, round(r* 2 * n) + 1);
  for i := 0 to round(r * 2 * n) do
    begin
      y := sqrt( sqr(r) - sqr(r - (i / n)) );
      mOut.Lines.Text := mOut.Lines.Text + createOutXY(y, r, n, (i / n));
      arr[i] := y
    end;
  for i := 1 to high(arr) - 1 do
    begin
      for j := 0 to round(arr[i] * 2 * n) do
        begin
          y := sqrt( sqr(arr[i]) - sqr(arr[i] - (1 / n) )); //****************************************
          mOut2.Lines.Text := mOut2.Lines.Text + createOutYZ(y, arr[i], n, i)
        end
    end

jetzt funktioniert ja fast alles so wie es soll...
nur statt

Delphi-Quelltext
1:
y := sqrt( sqr(arr[i]) - sqr(arr[i] - (1 / n) ));                    

müsste

Delphi-Quelltext
1:
y := sqrt( sqr(arr[i]) - sqr(arr[i] - (j / n) ));                    

stehen, dann gibts aber wieder die oben erwähnte Fehlermeldung..

Irgendjemand ne Idee ?


EUOCheffe - Do 23.12.04 06:46

Hmmmm, ohne das jetzt genau anzugucken... Wurzeln aus negativen Zahlen sollte man möglichst nicht ziehen, wenn man nachher nicht im Komplexen weiterrechnen will. Wäre zumindest ein Grund für den Fehler bei der Wurzeloperation.


ShadowCaster - Do 23.12.04 10:33

Der Meinung bin ich auch. Kleiner Tipp: du könntest zum Beispiel eine If-Abfrage einbauen, ob
sqr(arr[i]) - sqr(arr[i] - (1 / n) ) < 0 ist. Wenn das der Fall ist, müsstest du auf Fehlersuche gehen. Da ich allerdings wenig Zeit habe, kann ich mir den Code leider nicht näher anschauen (sorry).