Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Array Zugriff (https://www.delphipraxis.net/164730-array-zugriff.html)

Slashmob 27. Nov 2011 17:11


Array Zugriff
 
Nabend zusammen,

ich arbeite zurzeit an einem Projekt, das eine Tabelle von Cos-Werten im Bereich von 0° bis 90°
(in 1/10° Schritten, d.h 901 Cos-Werte) erzeugen soll, dann anschließend diese Tabelle übernommen und in ein Array eingelesen wird.
Ziel ist es alleine durch die obige Cos-Tabelle (0°-90°) die Werte von Sinus, Cosinus und Tangens im Bereich von 0° bis 360° zu "berechnen", indem man die richtigen Verhältnisse von Cos aus dem ersten Quadranten zu den übrigen Quadranten erstellt.

Mein Problem ist, dass ich den Zugriff auf den Array nicht hinbekomme. Da kommt immer totaler Quatsch als Wert raus. Ich hab wohl irgendwo einen Denkfehler oder übersehe etwas. :?
Weil mich dieser letzte Teil schon seit zwei Tagen plagt, wollt ich euch um Hilfe, Anregungen oder Tipps bitten.

Gruß Slash

Mein Code sieht wie folgt aus:

Code:
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, MaskEdit,
  StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    MaskEdit1: TMaskEdit;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var                          // Globale Deklaration
  Form1: TForm1;
  cos_Tab: array [0..900] of double;
  f: textfile;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject); // Tabelle erzeugen und speichern
Var s: string;    // Zeichenkette
    i: integer;  // Laufindex
begin
     assignfile(f,'cos.txt');  
     rewrite(f);              
     For i:= 0 to 900 Do      
         Begin
              s:=floattostr(cos((i/10)*(2*Pi/360)));
              writeln(f,s);      
         end;
     closefile(f);      
end;

procedure TForm1.Button2Click(Sender: TObject);  // Tabelle übernehmen und in Array einlesen
Var s: string;
    i: integer;
begin
     assignfile(f,'cos.txt');    
     reset(f);                  
     For i:=0 to 900 Do          
         Begin
              readln(f,s);      
              cos_Tab[i]:=strtofloat(s);
         end;
     closefile(f);
end;

procedure TForm1.Button3Click(Sender: TObject); // Berechne Funktionswert
Var i,quadrant: integer;
    winkel, rad, coswert,sinwert,tanwert: double;

begin
     winkel:=strtofloat(maskedit1.text);  
     If (winkel>360) then                
     showmessage ('Wert zu groß! Bitte einen Wert zwischen 0° und 360° eingeben!');
     If (winkel<0) then
     showmessage ('Negativer Wert! Bitte einen Wert zwischen 0° und 360° eingeben!');
     rad:= (winkel*2*Pi)/360;


     // Quadrantnummer aus Grenzwinkeln bestimmen
     If ((winkel*10)>=0) and ((winkel*10)<=900) then
     Begin
           quadrant:= 1;
     end;
     If ((winkel*10)>900) and ((winkel*10)<=1800) then
     Begin
           quadrant:= 2;
     end;
     If ((winkel*10)>1800) and ((winkel*10)<=2700) then
     Begin
           quadrant:= 3;
     end;
     If ((winkel*10)>2700) and ((winkel*10)<=3600) then
     Begin
           quadrant:= 4;
     end;

// Funktionsberechnung

     Case quadrant of
     1: begin
          coswert:=cos_Tab[i];

        end;
     2: begin
          coswert:=-cos_Tab[1800-i];

        end;
     3: begin
          coswert:=-cos_Tab[1800+i];

        end;
     4: begin
          coswert:=cos_Tab[3600-i];

        end;
     end;

// Ausgabe der Funktionswerte
     label1.Caption:='Cos-Wert: '+ floattostr(coswert);
     label2.Caption:='Sin-Wert: '+ floattostr(sinwert);
     label3.Caption:='Tan-Wert: '+ floattostr(tanwert);

end;

procedure TForm1.FormCreate(Sender: TObject);
begin

end;

end.

Bjoerk 27. Nov 2011 17:48

AW: Array Zugriff
 
I ist nicht definiert.

MGC 27. Nov 2011 17:55

AW: Array Zugriff
 
Hallo,

momentan scheinst Du mit einem eindimensionalen Array zu arbeiten, auf diese Weise hast Du im Prinzip eine Art Zahlenstrahl erzeugt, möchtest jedoch Quadranten erzeugen.
Am besten ist es Du visualisierst einmal innerhalb einer Tabelle (ist ja auch ein Array), wie viele Quadranten Du benötigst und wie viele Zahlen Du innerhalb eines Quadranten hast.
Bedenke dabei, das Quadrant vom Wort Quadrat abgeleitet ist und das innerhalb einer Zeile genauso viele Zahlen stehen müssen, wie Dein Quadrant Zeilen hat.

Eine wichtige Frage wäre nun, ob Du von vorn herein ein multidimensionales Array erzeugen möchtest, welches Du über Quadrantenindex, Zeilenindex und Zahlenindex ansprichst oder ob Du ein Zweidimensionales quadratisches Array anlegen möchtest, das Du anhand des Index rechnerisch in Quadranten unterteilst (Zeile 1 - 10 & Reihen 1 - 10 = 1. Quadrant usw.).

Eine solche Aufgabe zu einer Zahlenmatrix ist eine sehr gute Vorübung, falls Du später einmal komplexere Matrices verarbeiten musst, z.B. Auswertung eines Nahinfrarot-Spektrums zur Nährwetranalyse in verschiedenen Proben.

// EDIT: Stimmt, die Variable I ist in der Tat im Button3Click nicht definiert, bzw. nicht sinnvoll belegt.


Viele Grüße,

Slashmob 27. Nov 2011 18:39

AW: Array Zugriff
 
@Bjoerk: I ist nicht definiert, weil das doch der Laufindex von 0 bis 900 ist.


@MGC: Ja, also ich hab die Tabelle, die 901 Cos-Werte, die sind im Array gespeichert.

Meine konkrete Frage ist, wieso hier im letzten Teil die Berechnung nicht klappt?
Wird hier der Zugriff auf cos_Tab[i] durchgeführt?

Code:
Case quadrant of
     1: begin
          coswert:=cos_Tab[i];

        end;
     2: begin
          coswert:=-cos_Tab[1800-i];

        end;
     3: begin
          coswert:=-cos_Tab[1800+i];

        end;
     4: begin
          coswert:=cos_Tab[3600-i];

        end;
     end;

*kopfraucht*

Aphton 27. Nov 2011 18:42

AW: Array Zugriff
 
Debuggen -> Nachkucken, was für nen Wert "i" hat.
"i" erhält nirgends nen Wert zugewiesen -> dh. da steht irgendetwas drinnen!!

Ach mein Freund, deine Tabelle geht ja von 0..900, nicht?
Wie willst du dann die folgenden Indizes ansprechen:
[1800+i], [3600-i]

Uwe Raabe 27. Nov 2011 21:20

AW: Array Zugriff
 
Ersetz mal dieses

Delphi-Quellcode:
     // Quadrantnummer aus Grenzwinkeln bestimmen
     If ((winkel*10)>=0) and ((winkel*10)<=900) then
     Begin
           quadrant:= 1;
     end;
     If ((winkel*10)>900) and ((winkel*10)<=1800) then
     Begin
           quadrant:= 2;
     end;
     If ((winkel*10)>1800) and ((winkel*10)<=2700) then
     Begin
           quadrant:= 3;
     end;
     If ((winkel*10)>2700) and ((winkel*10)<=3600) then
     Begin
           quadrant:= 4;
     end;

// Funktionsberechnung

     Case quadrant of
     1: begin
          coswert:=cos_Tab[i];

        end;
     2: begin
          coswert:=-cos_Tab[1800-i];

        end;
     3: begin
          coswert:=-cos_Tab[1800+i];

        end;
     4: begin
          coswert:=cos_Tab[3600-i];

        end;
     end;
durch dieses

Delphi-Quellcode:
     
     I := winkel*10;
     // an dieser Stelle gilt: 0 <= winkel <= 360,
     // also auch: 0 <= I <= 3600
     if (I <= 900) then
       coswert := cos_Tab[I]         // 0..90
     else If (I <= 1800) then
       coswert := -cos_Tab[1800 - I] // 90..180
     else If (I <= 2700) then
       coswert := -cos_Tab[I - 1800] // 180..270
     else
       coswert := cos_Tab[3600 - I]; // 270..360
Durch die Verwendung von ELSE ersparst du dir die Abfrage der unteren Grenzen. Da du vorher schon den Bereich 0..360 kontrollierst, kann diese Überprüfung ebenfalls entfallen.

Bjoerk 27. Nov 2011 22:07

AW: Array Zugriff
 
Mein Vorschlag wäre, nur die ganzzahligen Winkel zu vertafeln und Zwischenwerte geradlinig zu interpolieren.

Delphi-Quellcode:
var
  CosTable: array [0..90] of double;

function CosFromCosTable(Alpha: integer): double;
var
  I: integer;
begin
  while Alpha <  0 do Inc(Alpha, 360);
  while Alpha > 360 do Dec(Alpha, 360);
  I:= 1;
  if Alpha > 180 then
  begin
    Dec(Alpha, 180);
    I:= -1;
  end;
  if Alpha <= 90 then
    Result:= I * CosTable[Alpha]
  else
    Result:= - I * CosTable[180 - Alpha];
end;

function SinFromCosTable(Alpha: integer): double;
begin
  Result:= CosFromCosTable(90 - Alpha);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  Alpha: integer;
begin
  for Alpha:= 0 to 90 do
    CosTable[Alpha]:= Cos(Alpha * 0.0174532925199433);
end;

MGC 28. Nov 2011 08:04

AW: Array Zugriff
 
Ich sehe schon, es wurden bereits spitzenmäßige Ansätze übermittelt. Wobeio ich jedoch ein multidimensionales Array bevorzugen würde, wobei der Wuadrant bereits als erster Index dienen würde. Auf diese Weise kann man, meiner Meinung nach, schneller und übersichtlicher durch das Array navigieren udn seine Vergleichswerte auslesen.

Viele Grüße,

Sir Rufo 28. Nov 2011 09:26

AW: Array Zugriff
 
Zitat:

Zitat von MGC (Beitrag 1138180)
Ich sehe schon, es wurden bereits spitzenmäßige Ansätze übermittelt. Wobeio ich jedoch ein multidimensionales Array bevorzugen würde, wobei der Wuadrant bereits als erster Index dienen würde. Auf diese Weise kann man, meiner Meinung nach, schneller und übersichtlicher durch das Array navigieren udn seine Vergleichswerte auslesen.

Viele Grüße,

Ähmmm, das Salz in der Suppe bei diesem Ansatz ist es doch, dass nur die Werte für den ersten Quadranten berechnet und abgespeichert werden.
Alle Werte für die Quadranten 2-4 werden aufgrund der Werte vom Quadranten 1 ermittelt, die sich ja auch lediglich durch ein Vorzeichen, bzw. die Reihenfolge unterscheiden.

Slashmob 28. Nov 2011 14:20

AW: Array Zugriff
 
Zitat:

Zitat von Sir Rufo (Beitrag 1138192)
Zitat:

Zitat von MGC (Beitrag 1138180)
Ich sehe schon, es wurden bereits spitzenmäßige Ansätze übermittelt. Wobeio ich jedoch ein multidimensionales Array bevorzugen würde, wobei der Wuadrant bereits als erster Index dienen würde. Auf diese Weise kann man, meiner Meinung nach, schneller und übersichtlicher durch das Array navigieren udn seine Vergleichswerte auslesen.

Viele Grüße,

Ähmmm, das Salz in der Suppe bei diesem Ansatz ist es doch, dass nur die Werte für den ersten Quadranten berechnet und abgespeichert werden.
Alle Werte für die Quadranten 2-4 werden aufgrund der Werte vom Quadranten 1 ermittelt, die sich ja auch lediglich durch ein Vorzeichen, bzw. die Reihenfolge unterscheiden.

Richtig!

@all: Hab jetzt mein Problem mit euren Ansätzen lösen können. Funktioniert alles wunderbar!
Vielen Dank euch allen! :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:55 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz