![]() |
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. |
AW: Array Zugriff
I ist nicht definiert.
|
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, |
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* |
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] |
AW: Array Zugriff
Ersetz mal dieses
Delphi-Quellcode:
durch dieses
// 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;
Delphi-Quellcode:
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.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 |
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; |
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, |
AW: Array Zugriff
Zitat:
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. |
AW: Array Zugriff
Zitat:
@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 20:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz