AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

canvas - waagerechter wurf mit timer

Ein Thema von tar · begonnen am 21. Jun 2007 · letzter Beitrag vom 23. Jun 2007
Antwort Antwort
Seite 1 von 2  1 2      
tar

Registriert seit: 21. Jun 2007
5 Beiträge
 
Delphi 2005 Architect
 
#1

canvas - waagerechter wurf mit timer

  Alt 21. Jun 2007, 11:40
hi leute,

ich hab ne schulaufgabe bekommen, an der ich absolut nicht weiterkomme.

die aufgabe lautet:
stelle mittels canvas einen strahl aus einem loch aus einer defekten wasserleitung dar.
- die lochhöhe, sowie die geschwindigkeit des wassers sind per eingabe vorgegeben.


desweiteren soll festgestellt werden, ob der strahl in einen eimer trifft, dessen position man ebenfalls per eingabe verändern kann.

das ganze sieht derzeit wie folgt aus:

http://www.pro-lamer.net/d32_wl.png

input:
lochhöhe = h
geschwindigkeit = v
eimerposition = e

output:
wurfweite = w

sonst habe ich noch 3 dinge umbenannt:
Form1 = frm
Image1 = img
Timer = tmr

Code:
procedure buildimg (e: Integer);
begin
  clearimg;
  with frm.img.canvas do
  begin
  // Leitung
    brush.color:=$00CCCCCC;
    pen.color:=$00000000;
    rectangle(10,0,20,frm.img.height);
  // Eimer
    brush.color:=$0066FF66;
    pen.color:=$00448844;
    rectangle(20+e,frm.img.height-20,40+e,frm.img.height);
  end;
end;

procedure circle (x,y: Integer);
begin
  with frm.img.canvas do
  begin
  // Loch & Kreise
    brush.color:=$00FF6666;
    pen.color:=$00884444;
    ellipse(x,y,x+5,y+5);
  end;
end;

procedure Tfrm.Button1Click(Sender: TObject);
begin
// Eingabe
  a:=9.81/2;
  h:=strtoint(edt_in_h.text);
  v:=strtofloat(edt_in_v.text);
  e:=strtoint(edt_in_e.text);

  if (h<300) and (h>-1) and (e<261) and (e>-1) and (v>0) then
  begin
    x:=15;
    y:=frm.img.height-h;

    buildimg(e);
    circle(x,y);
    frm.tmr.enabled:=true;
  end
  else
  edt_out_w.text:='FEHLER!';

end;

procedure Tfrm.tmrTimer(Sender: TObject);
begin
  if (y<frm.img.height) then
  begin
//    y:=y+25;
    y:=y+round((a*x*x/(v*v))/150);
    x:=x+round(v*sqrt((y)/a));
    circle(x,y);
  end
  else
  begin
    w:=x;
    edt_out_w.text:=inttostr(w);
    frm.tmr.enabled:=false;      
  end;
end;
nun habe ich das problem, dass

1. w nicht korrekt ausgegeben wird.
das sieht man ja auf dem bild. der eimer ist 20pixel breit und der letzte wasserkreis sollte ja in dem eimer sein.)

2. ich keine regelmäßigen abstände nach unten habe, da y durch das intervall 150 geteilt wird. wenn ich stattdessen y:=y+25; (was hier auskommentiert ist) festlege, kommt seltsamerweise keine parabel mehr zustande. x wird irgendwie falsch berechnet - ich weiß nicht, warum.

3. der letzte wassertropfen sollte direkt auf dem boden aufkommen, da x aber wie gesagt falsch berechnet wird, kriege ich das nicht hin. ich habe es schon wie folgt ausprobiert:

Code:
procedure Tfrm.tmrTimer(Sender: TObject);
begin
  if (y<frm.img.height) then
  begin
//    y:=y+25;
    y:=y+round((a*x*x/(v*v))/150);
    x:=x+round(v*sqrt((y)/a));
    circle(x,y);
  end
  else
  begin
    y:=frm.img.height-5;
    x:=round(v*sqrt((y)/a));
    w:=x;
    edt_out_w.text:=inttostr(w);
    frm.tmr.enabled:=false;      
  end;
end;
wobei er aber x wieder falsch ausgibt. ich bin hier wirklich am verzweifeln. außerdem frage ich mich, wieso ich das überhaupt in einem timer ausgeben muss (teil der aufgabe).

ich bin echt für jede hilfe dankbar.
  Mit Zitat antworten Zitat
Benutzerbild von ChrisE
ChrisE

Registriert seit: 15. Feb 2006
Ort: Hechingen
504 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

Re: canvas - waagerechter wurf mit timer

  Alt 21. Jun 2007, 13:26
Hallo tar,

hier werden ja keine Hausaufgaben gelößt, dennoch möchte ich Dir einen Denkanstoß geben.

Der Waagrechte Wurf besteht ja aus zwei getrennten Bewegungen.
1. Bewegung in x-Richtung
Da diese Berechnung von einer reibungslosen Umgebung ausgeht, heißt das bei einer Geschwindigkeit V>0 ändert sich der Weg in X-Richtung linear (s = v*t). Bitte im Code beachten was passiert bei v = 0 !!!
2. Bewegung in y-Richtung
Da hier keine Anfangsgeschwindigkeit vorhanden ist (also Vy=0) wirkt nur die Erdbeschleunigung. Die Formel s = 1/2 * a *t^2 zeigt einem ja schon, dass der Weg in Y-Richtung von Zeitschritt zu Zeitschritt (Timer-Event) Größer wird (t geht quadratisch ein).
-> Folge wie auf der Abbildung zu sehen ist ist eine nach unten geöffnete Parabel.

Lösungsansatz:
Berechne im Timer mal nur mit diesen Formeln x und y. D.h.
Delphi-Quellcode:
// Vor der Timer-Routine:
TimerCount := 0;
v := ...
h := ...
//in der TimerRoutine:
inc(TimerCount);
t := TimerCount * Timer.Interval / 1000;
x := v * t; // Achtung: Hier muss danach noch die Koordinatenumrechnung auf die Canvas erfolgen
y := h - 0.5 * 9.81 * t; // Achtung: Hier muss noch die Koordinatenumrechnung auf die Canvas erfolgen
Das sollte, wie ich denke als Hilfestellung reichen

Gruß, Chris
Christian E.
Es gibt 10 Arten von Menschen, die die Binär lesen können und die die es nicht können

Delphi programming rules
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#3

Re: canvas - waagerechter wurf mit timer

  Alt 21. Jun 2007, 13:29
Du solltest zunächst einmal die Formel für den schrägen Wurf in einer eigenen Function isolieren.
Überleg dir, welche Parameter in die Formel reinkommen (Gewschwindigkeit, Winkel, Zeit, ...) und was das Ergebnis ist.
Die Formel sollte davon ausgehen, dass der Wurf auf Höhe 0 gestartet wird.
Denk daran, dass es für Punkte den Datentyp TPoint gibt; du brauchst also x- und y-Wert nicht in 2 Variablen übergeben.
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von divBy0
divBy0

Registriert seit: 4. Mär 2007
Ort: Sponheim
1.021 Beiträge
 
Delphi XE2 Professional
 
#4

Re: canvas - waagerechter wurf mit timer

  Alt 21. Jun 2007, 13:29
Hallo!

zu 1. das verstehe ich nicht ganz... ist denn da nicht einfach nur die Position falsch angegeben?

zu 2. naja, eine Parabel bekommst du glaub ich auch nur, wenn du in der Formel irgendwo was mit x^2 drin hast oder nicht?

zu 3. du fängst doch von dem Rohr an gesehen zu rechnen, oder? vielleicht kannst du ja eine "Abschlussberechnung" für den letzten Tropfen bei x=0 (also dem Boden) zusätzlich machen oder du musst bei jedem Tropfen ein Offset abziehen, was dann aber auch die Kurve verschiebt.
Marc
  Mit Zitat antworten Zitat
Benutzerbild von Nikolas
Nikolas

Registriert seit: 28. Jul 2003
1.528 Beiträge
 
Delphi 2005 Personal
 
#5

Re: canvas - waagerechter wurf mit timer

  Alt 21. Jun 2007, 13:43
Lass die Finger lieber weg von so gleichungen wie für den schrägen Wurf. Wenn du das nicht herleiten kannst, ist es Unsinn, sowas zu nutzen. Die beste Methode ist sicher die von Chris. Du hast zwei getrennte Funktionen, eine für x, eine für y. Beide sind sehr einfach. (konstante geschwindigkeit und konstante Beschleunigung)
Du nimmst also zwei Funktionen x(t) und y(t), die dir jeweils einen real, oder sowas, geben. Für jeden Zeitpunkt kannst du dir dann die Position berechnen.
Damit ist auch die Berechnung für den Eimer einfacher, als Pixel zu zählen:
Du kannst dir ausrechnen, wann der Tropfen landen (da ist y(t)=0). Du hast also so eine gleichung wie y(t)=Fallhöhe-g/2t^2=0
damit kannst du dann t bestimmen. Wenn du diese zeit dann in x(t) eingibst, weisst du, wo der Tropfen landet. Das kannst du dann mit der Eimerkoordinate vergleichen (if eimer.x-10<tropfen<eimer.x+10) oder so.
Erwarte das Beste und bereite dich auf das Schlimmste vor.
  Mit Zitat antworten Zitat
tar

Registriert seit: 21. Jun 2007
5 Beiträge
 
Delphi 2005 Architect
 
#6

Re: canvas - waagerechter wurf mit timer

  Alt 21. Jun 2007, 15:01
hallo ChrisE,

ich habe ein wenig herumprobiert. deine methode ändert nichts an den problemen, sie verkürzen nur das zeitinterval, welches aber nichts an den y-abständen ändert (durch beschleunigung wohl nicht möglich).

ich bin weiterhin am verzweiffeln, wie genau er das (vor allem letzte X) ausrechnet. die koordinaten stimmen einfach irgendwie nicht - trotz verwendung der richtigen formeln.

sieht man deutlich an diesem bild:

http://www.pro-lamer.net/d32_wl2.png

Delphi-Quellcode:
procedure Tfrm.Button1Click(Sender: TObject);
begin
// Eingabe
  a:=9.81/2;
  h:=strtoint(edt_in_h.text);
  v:=strtofloat(edt_in_v.text);
  e:=strtoint(edt_in_e.text);

  if (h<300) and (h>-1) and (e<281) and (e>19) and (v>0) then
  begin
    i:=0;
    x:=15;
    y:=frm.img.height-h;

    buildimg(e);
    circle(x,y);
    frm.tmr.enabled:=true;
  end
  else
  edt_out_w.text:='Eingaben falsch!';
end;

procedure Tfrm.tmrTimer(Sender: TObject);
begin
  if (y<frm.img.height) then
  begin
    inc(i);
    t:=i*frm.tmr.interval/50;
    y:=y+(a*t);
    x:=15+(v*t);
    circle(x,y);
  end
  else
  begin
    w:=round(x);
    if (w>e) and (w<e+20) then
    begin
      edt_out_w.text:=inttostr(w)+' Treffer!';
      frm.tmr.enabled:=false;
    end
    else
    begin
      edt_out_w.text:=inttostr(w)+' Daneben!';
      frm.tmr.enabled:=false;
    end;
  end;
end;
rest wie oben
  Mit Zitat antworten Zitat
tar

Registriert seit: 21. Jun 2007
5 Beiträge
 
Delphi 2005 Architect
 
#7

Re: canvas - waagerechter wurf mit timer

  Alt 21. Jun 2007, 15:11
hallo Nikolas,

das mit der formel und der zeit bei y=0 (also eigentlich y=frm.img.height (in meinem fall 300)) kriegst du nicht gebacken, da:

y = y+(a*t)

umgestellt nach t:

t = (y-y)/a = 0/a = 0

ergibt! damit bleibt für die rechnung von x kein zeitfaktor übrig:

x = 15+(v*t) = 15+0

anders gerechnet, kommt bei x irgendwas dubioses raus:

y = a*t = 300
t = y/a = 300/a
x = 15+(v*t)

wobei der ausgebene wert immer weit vom "strahl" entfernt ist. ich muss irgendwas übersehen.
  Mit Zitat antworten Zitat
Benutzerbild von Nikolas
Nikolas

Registriert seit: 28. Jul 2003
1.528 Beiträge
 
Delphi 2005 Personal
 
#8

Re: canvas - waagerechter wurf mit timer

  Alt 21. Jun 2007, 17:01
Zitat:
das mit der formel und der zeit bei y=0 (also eigentlich y=frm.img.height (in meinem fall 300)) kriegst du nicht gebacken, da:
Du vielleicht nicht, ich schon

Zitat:
y = y+(a*t)
Es könnte z.B. daran liegen, dass das hier Unsinn ist. Was soll das denn bedeuten? Ich habe dir doch oben schon die richtige Gleichung hingeschrieben. Du darfst doch nicht einfach eine Zeile aus einer Schleife in einem Code nehmen und denken, du könntest damit mathe machen..
Erwarte das Beste und bereite dich auf das Schlimmste vor.
  Mit Zitat antworten Zitat
tar

Registriert seit: 21. Jun 2007
5 Beiträge
 
Delphi 2005 Architect
 
#9

Re: canvas - waagerechter wurf mit timer

  Alt 22. Jun 2007, 09:11
ja nikolas, ich habe ganz einfach y nicht mit der höhe gleichgesetzt, sondern mit den bild-koordinaten (also 300-höhe), was ja nicht funktionieren konnte und so hat er immer falsch gerechnet. ich musste die koordinaten später beim kreismalen nur anpassen und nun klappts.

also, ich habe die berechnung jetzt hinbekommen, allerdings immer noch ein problem:

es gibt nun die 2 formeln:

x = v * t
y = g/2 * t²

daraus ergibt sich für die zeit:

t = x / v
t = sqrt(2*y/g)

daraus ergeben sich für x und y:

x = v * sqrt(2*y/g)
y = g/2 * x*x / (v*v)

hiermit wird die zeit einfach nicht mehr benötigt!

demzufolge ergibt sich nun folgender code:

Delphi-Quellcode:
procedure circle (x,y: Real);
begin
  with frm.img.canvas do
  begin
  // Loch & Kreise
    brush.color:=$00FF6666;
    pen.color:=$00884444;
    ellipse(round(x),frm.img.height-round(y),round(x)+5,frm.img.height-round(y)+5);
  end;
end;

procedure Tfrm.Button1Click(Sender: TObject);
begin
// Eingabe
  a:=9.81/2;
  h:=strtoint(edt_in_h.text);
  v:=strtofloat(edt_in_v.text);
  e:=strtoint(edt_in_e.text);

  if (h<300) and (h>-1) and (e<281) and (e>19) and (v>0) then
  begin
    i:=0;
    x:=15;
    y:=h;

    buildimg(e);
    circle(x,y);
    frm.tmr.enabled:=true;
  end
  else
  edt_out_w.text:='Eingaben falsch!';
end;

procedure Tfrm.tmrTimer(Sender: TObject);
begin
  if (y>5) then // Versuch, abzufangen
  begin
    y:=y-((a * x*x / (v*v))/frm.tmr.interval);
    x:=x+((v * sqrt(y/a))/frm.tmr.interval);
    circle(x,y);
  end
  else
  begin
    w:=round(x);
    if (w>e-1) and (w<e+21) then
    begin
      edt_out_w.text:=inttostr(w)+' Treffer!';
      frm.tmr.enabled:=false;
    end
    else
    begin
      edt_out_w.text:=inttostr(w)+' Daneben!';
      frm.tmr.enabled:=false;
    end;
  end;
end;
das problem ist nun, dass das programm y irgendwie nicht immer rechtzeitig abfangen kann und dann einen fehler erzeugt:

"invaliding float point operation." und auf diese zeile verweist:

Delphi-Quellcode:
y:=y-((a * x*x / (v*v))/frm.tmr.interval);
x:=x+((v * sqrt(y/a))/frm.tmr.interval); // <-- diese
nur habe ich das aber doch schon abgefangen mit y>5, so dass er gar nicht "über den bildrand" darf?
und wieso kann er nicht mit y<5 rechnen? selbst wenn y negativ wär? den kreis würde man ja eh nicht mehr sehen.
  Mit Zitat antworten Zitat
Benutzerbild von g0rmed
g0rmed

Registriert seit: 3. Apr 2007
Ort: Sülzetal
64 Beiträge
 
Delphi 2005 Personal
 
#10

Re: canvas - waagerechter wurf mit timer

  Alt 22. Jun 2007, 11:58
Ich hab jetzt nicht die ganze Disskussion mitverfolgt aber ich denke das Umstellen nach t
Zitat:
t = x / v
t = sqrt(2*y/g)
und dann wieder einsetzen geht nicht...da drehst du dich doch im Kreis(oder?).
Ich würde einfach eine Formel nach t umstellen und die in die andere einsetzen.
Zitat:
(1) y = g/2 * t²
t = x / v in (1)
=> y = (g/(2*v²)) * x²
Das ist dann die Gleichung für die Parabel ohne t.
Die Umsetzeung mit Delphi gestaltet sich dannnoch etwas anders, aber das mathematisch/physikalische Problem ist imho damit gelöst.
Hans
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:45 Uhr.
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