Entwickler-Ecke

Sonstiges (Delphi) - Paintbox Dreieck


Uni - Sa 20.03.10 11:00
Titel: Paintbox Dreieck
Hallo,
wir haben ein Programm, dass, wenn man 2 Seiten gegeben hat
die dritte Seite und die Winkel berechnet.
Als Zugabe soll das berechnete Dreieck (es ist rechtwinklig)
in Paintbox gezeichnet werden.

Wir haben nun schon hin und her probiert, die Grundbefehle sind auch klar,
wir haben aber keine Ahnung, wie man die berechneten Seitelängen auf die Paintbox übertragen kann,
da die Typen ja inkompatibel sind (Integer und Real).

Wisst ihr, wie dass umzusetzen ist?


turboPASCAL - Sa 20.03.10 11:08

Dann nutzt die Suche in der Delphi-Reference ROUND oder Suche in der Delphi-Reference TRUNC -Funktion. ;)


Uni - Sa 20.03.10 11:16

funktioniert natürlich trotzdem nicht, der Typ ist ja noch derselbe.

ich hab dass nun folgendermaßen geschrieben:


PaintBox1.Canvas.Rectangle (0,0,paintbox1.height,paintbox1.width);
Canvas.MoveTo(300,80);
Canvas.LineTo(a,80);
Canvas.LineTo(b,y-b);
Canvas.LineTo(300,80);


Xentar - Sa 20.03.10 11:56

Mit round machst du aus nem float einen Integer..
Natürlich müssen die Variablen auch als integer deklariert sein.


Uni - Sa 20.03.10 12:49

Genau dass ist doch das Problem. Für die Berechnung müssen die Werte Real sein. Und dann für das zeichen Integer. Wenn ich nun also Trunc oder Round verwende, dann bringt das gar nichts. Ich poste mal den kompletten Quelltext.


procedure TForm1.Button1Click(Sender: TObject);
const w3= 90;
var a,b,c,w1,w2,u,F:Real;
P1,P2,P3: TPoint;
t: String;
Seite:Integer;
begin
a:= StrToFloat(Edit1.Text);
b:= StrToFloat(Edit2.Text);
c:= Sqrt(Sqr(a)+ Sqr(b));
t:='Seite c beträgt '+ FloatToStrF(c,ffFixed,6,2)+ 'cm.';
Label4.Caption:= t;
u:= a+b+c;
t:='Der Umfang beträgt '+ FloatToStrF(u,ffFixed,6,2)+ 'cm.';
Label7.Caption:=t;
F:= 0.5 *(a*b);
t:= 'Der Flächeninhalt beträgt '+ FloatToStrF(F,ffFixed,6,2)+'cm².';
Label8.Caption:=t;
w1:=arcsin(a/c);
w1:= radToDeg(w1);
t:= 'Der Winkel Alpha beträgt ' + FloatToStrF(w1,ffFixed,6,2)+'°';
Label5.Caption:=t;
w2 :=arcsin(b/c);
w2:= RadToDeg(w2);
t:= 'Der Winkel Beta beträgt ' + FloatToStrF(w2,ffFixed,6,2)+'°';
Label6.Caption:=t;

a:= round(a);
b:= round(b);
c:= round(c);
PaintBox1.Canvas.Rectangle (0,0,paintbox1.height,paintbox1.width);
Canvas.MoveTo(300,80);
Canvas.LineTo(a,80);
Canvas.LineTo(b,y-b);
Canvas.LineTo(300,80);
end;

end.


Jakob_Ullmann - Sa 20.03.10 13:02

Also erstens mal sind deine Zeichenanweisungen schonmal nicht richtig. Wenn du bloß Canvas schreibst, wird das ganze als TForm1.Canvas interpretiert, da du in TForm1.Button1Click schreibst. Also wenn schon das PaintBox1 davor oder with-do Konstruktion verwenden.

Zweitens ist Real nur noch aus Kompatibilitätsgründen dabei, man sollte stattdessen lieber zum Beispiel Single oder Double nehmen (bzw. Extended).

Der Vorschlag mit Trunc und Round ist absolut korrekt. Du kannst zum Beispiel folgendes machen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
var
  x, y: Single;
begin
  x := 3.5;
  y := 1.5;
  x := x * 13// x = 45.5
  y := y * 11// y = 16.5

  with PaintBox1.Canvas do
  begin
    Canvas.Pixels[trunc(x), trunc(y)] := clRed;  // Pixel (45, 16) rot
    Canvas.Pixels[round(x), round(y)] := clBlue; // Pixel (46, 16) blau
  end;
end;


Das hat die Bedeutung:

- trunc (v. truncate) schneidet die Dezimalstellen ab
- round rundet auf die nächstgelegene gerade Zahl
- ceil (en.: ceiling: Decke) rundet auf die nächstgrößere ganze Zahl
- floor (en: Fußboden) rundet auf die nächstkleinere ganze Zahl

für positive Zahlen ist also trunc = floor, für negative ist trunc = ceil.

edit: natürlich geht auch:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var
  x: Single;
  _x: Integer;
begin
  x := sqrt(2);
  _x := trunc(x); // _x = 1
end;


edit2: Konstruktionen wie


Delphi-Quelltext
1:
2:
t := '...';
Label5.Caption := t;


sind unsinnig, da TCaption mit string kompatibel ist. Würde mich auch wundern, wenn der Delphi-Compiler das nicht automatisch optimiert. So geht es besser:


Delphi-Quelltext
1:
Label5.Caption := '...';                    


Uni - Sa 20.03.10 13:26

wahrscheinlich bin ich zu blöd dafür, aber es funktioniert einfach nicht.
Könntest du mir an meinem Quelltext zeigen, wo ich genau was verändern muss?


Xentar - Sa 20.03.10 13:29

user profile iconUni hat folgendes geschrieben Zum zitierten Posting springen:
wahrscheinlich bin ich zu blöd dafür, aber es funktioniert einfach nicht.
Könntest du mir an meinem Quelltext zeigen, wo ich genau was verändern muss?

Fehlermeldung?


Jakob_Ullmann - Sa 20.03.10 13:30


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
a:= round(a);
b:= round(b);
c:= round(c);
PaintBox1.Canvas.Rectangle (0,0,paintbox1.height,paintbox1.width);
Canvas.MoveTo(300,80);
Canvas.LineTo(a,80);
Canvas.LineTo(b,y-b);
Canvas.LineTo(300,80);


So geht das natürlich nicht. Hier wäre es am Übersichtlichsten, den var-Abschnitt um _a, _b, _c: Integer; zu ergänzen. Dann änderst du das entsprechend, also


Delphi-Quelltext
1:
2:
3:
_a := round(a);
{ usw. }
PaintBox1.Canvas.LineTo(_b, y - _b)


wobei ich jetzt keine Ahnung habe, wo du das y hernimmst. Ggf. muss das halt auch noch angepasst werden.


Uni - Sa 20.03.10 13:33

bei der einen Version kommt "Deklaration erwartet aber Canvas (bzw Paintbox1.) gefunden.
Bein der anderen sind Real und Integer noch immer inkompatibel;


platzwart - Sa 20.03.10 13:34

WAS funktioniert denn nicht? Ohne exakte Fehlerbeschreibung können wir nur raten. Außerdem hat dir Jakob_Ullmann doch genau beschrieben, was du wo ändern musst:
* das muss weg: a:= round(a);
* und dafür das round an die stelle, wo a als Integer interpretiert werden soll: MoveTo(100, round(a));


// Edit: zu langsam


Uni - Sa 20.03.10 13:39

als ich die Antwort gepostet habe, da stand die Nachicht von Jakob_Ullmann noch nicht dort.

Außerdem zeichnet es zwar jetzt etwas, aber eben nicht das gewünschte dreieck und auch nicht in der vorgegebenen Paintbox.


platzwart - Sa 20.03.10 13:41

Hast du auch an allen Stellen das "PaintBox1" ergänzt?


Uni - Sa 20.03.10 13:44

jetzt ist es zwar in der Paintbox, jedoch nicht mit den richtigen Längen.


platzwart - Sa 20.03.10 13:45

Kannst du bitte nochmal den gesamten Quelltext posten? (bitte mit <span class="inlineSyntax"><span class="codecomment">{PROTECTTAG6a28c369fdd9fd44727f1f9afec69126}</span></span> markieren)


Uni - Sa 20.03.10 13:48


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:
procedure TForm1.Button1Click(Sender: TObject);
const w3= 90;
var a,b,c,w1,w2,u,F:Real;
    t: String;
    a1,b1: Integer;
begin
a:= StrToFloat(Edit1.Text);
b:= StrToFloat(Edit2.Text);
c:= Sqrt(Sqr(a)+ Sqr(b));
t:='Seite c beträgt '+ FloatToStrF(c,ffFixed,6,2)+ 'cm.';
Label4.Caption:= t;
u:= a+b+c;
t:='Der Umfang beträgt '+ FloatToStrF(u,ffFixed,6,2)+ 'cm.';
Label7.Caption:=t;
F:= 0.5 *(a*b);
t:= 'Der Flächeninhalt beträgt '+ FloatToStrF(F,ffFixed,6,2)+'cm².';
Label8.Caption:=t;
w1:=arcsin(a/c);
w1:= radToDeg(w1);
t:= 'Der Winkel Alpha beträgt ' + FloatToStrF(w1,ffFixed,6,2)+'°';
Label5.Caption:=t;
w2 :=arcsin(b/c);
w2:= RadToDeg(w2);
t:= 'Der Winkel Beta beträgt ' + FloatToStrF(w2,ffFixed,6,2)+'°';
Label6.Caption:=t;

a1:= Round(a);
b1:= Round(b);

Paintbox1.Canvas.Rectangle (280,64,paintbox1.height,paintbox1.width);
Paintbox1.Canvas.MoveTo(280,64);
Paintbox1.Canvas.LineTo(a1,64);
Paintbox1.Canvas.LineTo(b1,b1-64);
Paintbox1.Canvas.LineTo(280,64);
end;

end.


platzwart - Sa 20.03.10 14:00

Soll der Punkt (280,64) der verschobene Ursprung sein? Dann musst du die berechneten Werte beim Zeichnen anpassen...


Uni - Sa 20.03.10 14:19

ja das Problem lag daran, dass ich die falschen Koordinaten angebeben habe, dennoch zeichnet es nicht das richtige dreieck.
Es ist nict rechtwinklig und die Seiten stimmen auch nicht :(


Jakob_Ullmann - Sa 20.03.10 14:36

Ist das denn wirklich so schwer??

- wir nehmen mal (ox | oy) als Koordinatenursprung
- dann haben die Punkte die Koordinaten:

* C = (ox | oy)
* A = (ox + b | oy)
* B = (ox | oy + a)

in der einfachsten Darstellung, nämlich dass der rechte Winkel unten links ist.


platzwart - Sa 20.03.10 14:37

Ich denke mal, was du da unten bei MoveTo und LineTo als Parameter stehen hast, stimmt nicht...


Jakob_Ullmann - Sa 20.03.10 14:40

user profile iconplatzwart hat folgendes geschrieben Zum zitierten Posting springen:
Ich denke mal, was du da unten bei MoveTo und LineTo als Parameter stehen hast, stimmt nicht...


Denke ich auch. Dazu müsste er aber entweder mal lesen, was so geantwortet wird, oder den aktuellen Quellcode schicken. :roll:


Uni - Sa 20.03.10 14:47

keine Sorge ich lese die antworten und inzwischen geht es auch.
Ich danke euch für eure wirklich sehr geduldige Hilfe. :)

Edit:Lieber Jakob, hier handelt es sich übrigens um eine sie und nicht um einen er ^^


Jakob_Ullmann - Sa 20.03.10 15:10

user profile iconUni hat folgendes geschrieben Zum zitierten Posting springen:
Lieber Jakob, hier handelt es sich übrigens um eine sie und nicht um einen er ^^


Werd's mir merken. :wink:


Xentar - Sa 20.03.10 15:43

user profile iconUni hat folgendes geschrieben Zum zitierten Posting springen:
Edit:Lieber Jakob, hier handelt es sich übrigens um eine sie und nicht um einen er ^^

Hättest du vorher sagen sollen, dann hättest direkt den korrekten Quellcode bekommen *duck* :D


Yogu - Sa 20.03.10 20:48

Bitte markiere deine Frage als erledigt, damit Hilfestellende sofort sehen, dass sie das Thema nicht durchlesen müssen. Klicke dazu einfach auf user defined image oberhalb des ersten Postings. Danke! :)