[GELÖST] Wurfparabel wird falsch gezeichnet.

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
Soner
Beiträge: 726
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

[GELÖST] Wurfparabel wird falsch gezeichnet.

Beitrag von Soner »

Hallo Leute,
ich habe kleines Testprogramm erstellt um Wurfparabel darzustellen aber das Programm verhält sich irgendwie Merkwürdig. Wenn ich für Wurfwinkel 45° eingebe dann zeichnet es wie es sein soll im 1.Quadranten, bei 46° im 4., bei 47° auch im 4. Quadranten, bei 48° wieder im 1.Quadranten. So geht es abwechselnd weiter. Es muß für 0..90° alles im 1. Quadranten gezeichnet werden. (Schieferwurf). In Screenshots sieht ihr was ich meine. Ich konnte keinen Fehler entdecken, mehrere Augen sind besser als zwei. Kann jemand hier irgendein Fehler entdecken?

Code: Alles auswählen

 
unit mainform1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ComCtrls, ExtCtrls, Spin;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    ImgOhneLuftw: TImage;
    Label1: TLabel;
    Label2: TLabel;
    SpEdAlpha: TSpinEdit;
    SpEdVo: TSpinEdit;
    ToolBar1: TToolBar;
    ToolBtnDrawWurf: TToolButton;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    procedure FormCreate(Sender: TObject);
    procedure ImgOhneLuftwResize(Sender: TObject);
    procedure ToolBtnDrawWurfClick(Sender: TObject);
  private
    { private declarations }
    owp0x, owp0y : integer; //Koordinaten Ursprung bei ohne Lufwiderstand
  public
    { public declarations }
    procedure DrawAxis(AImg: TImage);
    procedure DrawParabOhneLuftwid;
  end;
 
var
  Form1: TForm1;
 
implementation
 
uses math;
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.FormCreate(Sender: TObject);
var aBmp: TBitmap;
begin
  aBmp:= TBitmap.Create;
   aBmp.Width:=ImgOhneLuftw.Width;
   aBmp.Height:=ImgOhneLuftw.Height;
   ImgOhneLuftw.Picture.Assign(aBmp);
   //DrawAxis(ImgOhneLuftw);
   //DrawParabOhneLuftwid;
end;
 
procedure TForm1.ImgOhneLuftwResize(Sender: TObject);
begin
  if not Assigned(ImgOhneLuftw.Picture.Bitmap) then exit;
  ImgOhneLuftw.Picture.Bitmap.Width:=ImgOhneLuftw.Width;
  ImgOhneLuftw.Picture.Bitmap.Height:=ImgOhneLuftw.Height;
end;
 
procedure TForm1.ToolBtnDrawWurfClick(Sender: TObject);
begin
  DrawAxis(ImgOhneLuftw);
  DrawParabOhneLuftwid;
end;
 
procedure TForm1.DrawAxis(AImg: TImage);
begin
  //Koordinaten Ursprung bei ohne Lufwiderstand
  owp0x:=10;//AImg.Width div 2;
  owp0y:=AImg.Height div 2;
 
  AImg.Canvas.Brush.Color:=clWhite;
  AImg.Canvas.FillRect(0,0,AImg.Width,AImg.Height);
  AImg.Canvas.Pen.Color:=clBlack;
  AImg.Canvas.Line(owp0x, 0, owp0x, AImg.Height); //y-Achse = vertikale linie
  AImg.Canvas.Line(0, owp0y, AImg.Width, owp0y);  //x-Achse
end;
 
procedure TForm1.DrawParabOhneLuftwid;
var x, y, a, v, xmax : integer;
    g, tana, cosa, k: double;      //Erdanziehungskraft
begin
  //ohne Luftwiderstand:  y= tan(a)*x - [ g / ( 2*v^2 * cos(a)^2 ) ] * x^2
  //                      v: Anfangsgeschwindigkeit in m/s; g: Erdanziegung in m/s²
  //formel von hier: http://m.schuelerlexikon.de/mobile_physik/Ballistische_Kurven.htm
  g:=9.81;  a:=SpEdAlpha.Value; v:=SpEdVo.Value;
  tana:=tan(a);
  cosa:=cos(a);
  k:= g / ( (2*v*v) * (cosa*cosa)  );  // = [ g / ( 2*v^2 * cos(a)^2 ) ]
 
  xmax:=ImgOhneLuftw.Width-owp0x-1;
  for x:=0 to xmax do begin
    //ohne luftwiderstand
    y:= Round( (tana*x) - ( k * x * x) );
    ImgOhneLuftw.Canvas.Pixels[owp0x+x,owp0y-y]:=clBlue; //-y weil bildschirmkoorniaten gehen von oben nach unten
  end;
end;
 
end.
 
Im Anhang findet ihr Screenshots und Programmquelltext als Zip-Datei.
Dateianhänge
Ausgabe bei Alpha=48°
Ausgabe bei Alpha=48°
Ausgabe bei Alpha=47°
Ausgabe bei Alpha=47°
Ausgabe bei Alpha=46°
Ausgabe bei Alpha=46°
Ausgabe bei Alpha=45°
Ausgabe bei Alpha=45°
Zuletzt geändert von Soner am Mi 19. Dez 2012, 20:46, insgesamt 1-mal geändert.

Soner
Beiträge: 726
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Wurfparabel wird falsch gezeichnet.

Beitrag von Soner »

Hier ist Quelltext für Programm:
Dateianhänge
wurfparabel.zip
Quelltext als Zip-Datei
(127.47 KiB) 83-mal heruntergeladen

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: Wurfparabel wird falsch gezeichnet.

Beitrag von MAC »

Ich hab lange nachgedacht, und kam zum Entschluss:
Dein Programm ist komplet richtig und macht alles Fehlerfrei :D

Das Problem liegt hier jedoch daran, das du meinst, du hast 45 Grad im Gradmaß eingegeben. Der PC aber denkt du hast 45 als Bogenmaß eingegeben(sinus/tangens/cosiun arbeiten alle mit Bogenmaß, zumindest in Lazarus ... ) (also 14,3 * Pi). Wenn du jetzt 47 "Grad" eingibst, nimmt der PC das wieder als Bogenmaß, hier: 14,9 * Pi.
Deshalb auch das unerwartete Ergebniss...

Bevor du den cosinus und Tangenz verwendest, solltest du DegtoRad verwenden. Dafür einfach die unit "math" ganz oben bei uses hinzufügen...

Code: Alles auswählen

tana:=tan(DegtoRad(a));
cosa:=cos(DegtoRad(a));

Code: Alles auswählen

Signatur := nil;

Soner
Beiträge: 726
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: [GELÖST] Wurfparabel wird falsch gezeichnet.

Beitrag von Soner »

Vielen Dank, daran habe ich nicht gedacht. Nach so vielen Jahren wieder Punkteabzug in Mathe wegen nicht Beachtung von Bogen- und Gradmaß :mrgreen:

Antworten