AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Windmühle, bei der die Flügelanzahl variabel ist
Thema durchsuchen
Ansicht
Themen-Optionen

Windmühle, bei der die Flügelanzahl variabel ist

Ein Thema von spox · begonnen am 28. Okt 2007 · letzter Beitrag vom 12. Nov 2007
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von spox
spox

Registriert seit: 23. Sep 2007
47 Beiträge
 
Delphi 7 Personal
 
#1

Windmühle, bei der die Flügelanzahl variabel ist

  Alt 28. Okt 2007, 15:09
Ich bin zurzeit an einer Windmühle, bei dem die Postition, Flügelanzahl und Höhe der Mühle variabel ist. Das "Haus" der Mühle habe ich schon fertig, nur komme ich bei den variablen Flügeln nicht weiter:
Delphi-Quellcode:
unit muehleU;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

const
 pi=3.1415;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
    procedure Muehle(anzahl,hoehe,x,y:integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
 Muehle (4,150,50,50);
end;

procedure TForm1.Muehle (anzahl,hoehe,x,y:integer);
var flange,nr,bm,x2,y2:integer;
begin
 with Image1.Canvas do
  begin
   moveTo (x,y);
   rectangle (x,y,x+round(hoehe/5),hoehe);
   moveTo (x+(round(hoehe/5)DIV 2),y+10);
   x2:= x+(round(hoehe/5)DIV 2);
   y2:= y+10;
   flange:= hoehe DIV 2 ;
   bm:= round((2*pi) / anzahl);
   for nr:= 1 to anzahl do
   begin
   lineTo (round(flange*cos(bm*nr)+(hoehe DIV 10)),round(-flange*sin(bm*nr)+60));
   moveTo (x2,y2);
   end;
  end;
end;

end.
Habt ihr Tipps bzw. Lösungen?
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Windmühle, bei der die Flügelanzahl variabel ist

  Alt 28. Okt 2007, 15:14
Ich denke, da kann man nur trigonometrisch rangehen. Also mit dem Anfangswinkel starten, den Endpunkt des Flügels ausrechnen (sin/cos), den Winkel ändern usw.
Delphi-Quellcode:
FluegelEndPunkt.X:=Drehpunkt.X+Cos(Winkel)*Fluegelradius;
FluegelEndPunkt.Y:=Drehpunkt.Y+Sin(Winkel)*Fluegelradius;
Hierbei wird der Winkel gegen den Uhrzeigersinn von der X-Achse aus gemessen.

[edit]Wie kann man denn so blöd sein... Danke, Nikolas[/edit]
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von Nikolas
Nikolas

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

Re: Windmühle, bei der die Flügelanzahl variabel ist

  Alt 28. Okt 2007, 15:33
Delphi-Quellcode:
FluegelEndPunkt.X:=Drehpunkt.X+Cos(Winkel);
FluegelEndPunkt.Y:=Drehpunkt.Y+Sin(Winkel);
Wobei Sinus und Cosinus auch noch mit dem Flügelradius multipliziert werden sollten, da man sonst nichts sieht.

Den Winkel zwischen zwei Flügeln findest du dann einfach per Winkel=2pi/Flügelanzahl raus, wenn dein Flügel nicht nur aus einem Strich sondern aus einem Dreieck bestehen soll, wäre so was eine Möglichkeit:
Delphi-Quellcode:
Winkel= 2pi/Flügelanzahl;
WinkelKlein = Winkel /3;
x=100;
y=100;
(pen.)moveto(x,y);
for i:=0 to Flügelanzahl do
 begin
 lineto(x+cos(winkel*i)*radius, y+sin(winkel*i)*radius);
 lineto(x+cos(winkel*i+winkelKlein)*radius, y+sin(winkel*i+winkelklein)*radius);
 lineto(x,y);
 end;
Ich habe den Code nicht getestet, er dürfte aber recht gut sein, hoffe ich mal.
Erwarte das Beste und bereite dich auf das Schlimmste vor.
  Mit Zitat antworten Zitat
Benutzerbild von spox
spox

Registriert seit: 23. Sep 2007
47 Beiträge
 
Delphi 7 Personal
 
#4

Re: Windmühle, bei der die Flügelanzahl variabel ist

  Alt 28. Okt 2007, 15:44
Danke schon mal für eure Antworten
Ich weiß nur nicht, wo ich jetzt den Code von Nikolas einbauen soll... Soll ich dafür die ganze Muehle Prozedure überschreiben?
Und noch was: Winkel und WinkelKlein hab ich doch noch gar nicht definiert . . . Das kann doch gar nicht funktionieren, oder?
  Mit Zitat antworten Zitat
Benutzerbild von Nikolas
Nikolas

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

Re: Windmühle, bei der die Flügelanzahl variabel ist

  Alt 28. Okt 2007, 15:51
Zitat:
Ich weiß nur nicht, wo ich jetzt den Code von Nikolas einbauen soll... Soll ich dafür die ganze Muehle Prozedure überschreiben?
Und noch was: Winkel und WinkelKlein hab ich doch noch gar nicht definiert . . . Das kann doch gar nicht funktionieren, oder?
Der soll dan die Stelle, an der du die Flügel zeichnest. Noch mehr Hilfe solltest du eigentlich nicht brauchen. Nimm dir doch einfach mal einen Taschenrechner, ein geodreieck und einen Bleistift und führe den Code einfach aus. Dann wirst du ihn sicher verstehen.
Und die zweite Frage ist nicht wirklich ernst gemeint, oder?

Delphi-Quellcode:
Winkelstart=t*Omega;
Winkel = 2pi/Anzahl;
WinkelAkt= Winkelstart;
for i:=0 to Anzahl do
 begin
 lineto(x+cos(WinkelAkt)*radius, y+sin(WinkelAkt)*radius);
 lineto(x+cos(WinkelAkt+winkelKlein)*radius, y+sin(WinkelAkt+winkelklein)*radius);
 lineto(x,y);
 WinkelAkt += Winkel;
 end;
Wenn du jetzt t und Omega gescheit setzt (z.B. in einem Timer) könntest du die Windmühle sogar zum rotieren bringen
Erwarte das Beste und bereite dich auf das Schlimmste vor.
  Mit Zitat antworten Zitat
Benutzerbild von spox
spox

Registriert seit: 23. Sep 2007
47 Beiträge
 
Delphi 7 Personal
 
#6

Re: Windmühle, bei der die Flügelanzahl variabel ist

  Alt 28. Okt 2007, 16:07
Das wäre mein nächster Schritt
Doch zunächst muss ich erstmal die Windräder hinkriegen. Und es will einfach nicht... Ich habe Apollonius Tipp befolgt, da meine Flügel keine Dreiecke, sondern einfach nur Striche sein sollen. Mein Programmcode sieht jetzt wie folgt aus:
Delphi-Quellcode:
unit muehleU;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

const
 pi=3.1415;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
    procedure Muehle(anzahl,hoehe,x,y:integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
 Muehle (4,150,50,50);
end;

procedure TForm1.Muehle (anzahl,hoehe,x,y:integer);
var flange,nr,bm,x2,y2, FluegelEndPunktX, FluegelEndPunktY:integer;
begin
 with Image1.Canvas do
  begin
   moveTo (x,y);
   rectangle (x,y,x+round(hoehe/5),hoehe);
   moveTo (x+(round(hoehe/5)DIV 2),y+10);
   x2:= x+(round(hoehe/5)DIV 2);
   y2:= y+10;
   flange:= hoehe DIV 2 ;
   bm:= round((2*pi) / anzahl);
   for nr:= 1 to anzahl do
   begin
   FluegelEndPunktX:=(hoehe DIV 10)+round(Cos(bm*nr));
   FluegelEndPunktY:=60+round(Sin(bm*nr));
   //lineTo (round(flange*cos(bm*nr)+(hoehe DIV 10)),round(-flange*sin(bm*nr)+60));
   lineTo (FluegelEndPunktX,FluegelEndPunktY);
   moveTo (x2,y2);
   end;
  end;
end;

end.
  Mit Zitat antworten Zitat
Benutzerbild von Nikolas
Nikolas

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

Re: Windmühle, bei der die Flügelanzahl variabel ist

  Alt 28. Okt 2007, 16:11
Und warum befolgst du nicht mal meinen Tipp?

Greif dir einen taschenrechner und gib doch mal das hier ein:

> FluegelEndPunktX:=(hoehe DIV 10)+round(Cos(bm*nr));

Was kommt da für ein Wert raus? Ist dieser Wert sinnvoll?
Erwarte das Beste und bereite dich auf das Schlimmste vor.
  Mit Zitat antworten Zitat
oldmax

Registriert seit: 27. Apr 2006
Ort: Gieboldehausen
167 Beiträge
 
#8

Re: Windmühle, bei der die Flügelanzahl variabel ist

  Alt 29. Okt 2007, 12:13
Hi
Es ist relativ einfach, Windmühlenflügel zu programmieren. Überlegen wir, was notwendig ist:
Ein Mittelpunkt, dazu eignet sich ein TPoint. Dieser Variablentyp beinhaltet einen x und einen y Wert.
Z.B.
Nabe : TPoint (Global )
Delphi-Quellcode:
Nabe.x:=256; // Beispiel, so initialisierst du deinen Mittelpunkt im FormCreate
Nabe.y:=55;
Zwei weitere Variablen machen Sinn

Delphi-Quellcode:
Gradzahl : Real; (Global) // veränderbare Winkelvariable für die Bewegung
AnzFluegel : Integer; (Global) // falls eine veränderbare Flügelzahl erwünscht....
Um eine Linie zu zeichnen benötigen wir nun einen Anfangspunkt und einen Endpunkt.
Also, Anfang ist Mitte, Endpunkt ist Flügellänge und Winkel von Mitte. Daraus machen wir eine Funktion, in der wir diese Werte als Parameter übergeben und einen TPoint-Wert erhalten:
Delphi-Quellcode:
Function TMyForm.Endpunkt( Radius: Integer; Winkel: Real; Zentrum : TPoint):TPoint;
Var xypunkt : TPoint;
Begin
   xypunkt.x:=Trunc(Cos(DegToRad(Winkel))*(-Radius))+Zentrum.x;
   xypunkt.Y:=Trunc(Sin(DegToRad(Winkel))*(-Radius))+Zentrum.Y;
   Result:= xypunkt;
End;
Nun die Zeichnung der Linie, am besten eine Procedur mit den Parametern Anfangspunk, Endpunkt und Farbe. Die Farbe brauchst du, um die alte Zeichnung wieder zu löschen. Nehmen wir an, du zeichnest auf einem grünen Untergrund. Eine Rote Linie ist sichtbar, eine grüne nicht...
Also
Delphi-Quellcode:
Procedure TMyForm.ShowFluegel(Anfang,Ende: Tpoint; Farbe : TColor);
Begin
   MyForm.Canvas.Pen:Color:=Farbe;
   MyForm.Canvas.Moveto(Anfang.x, Anfang.Y);
   MyForm.Canvas.Lineto(Ende.x, Ende.Y);
End;
Eigentlich lassen sich jetzt schon die Programmzeilen testen, wenn ich z.B. über ein Button erst mal einen Endpunkt errechne und dann anschließend die Anzeige aufrufe. Du willst aber die Flügellänge und die Anzahl der Flügel selbst bestimmen. Nun gut, 2 Editfelder mit den Werten und nun geht es los.

In die Ereignisroutine deines Tasters setzt du erst mal folgenden Code:

Delphi-Quellcode:
Procedure TMyForm.MyButtonClick(Sender:Tobject);
Var i : Integer;
      Sektorwinkel : Real;
      Kreispunkt : Tpoint;
Begin
    AnzFluegel :=StrToInt(Ed_Fluegel.Text); //Editfeld mit Namen ED_Fluegel // globale Variable setzen
    For i:=1 to AnzFluegel do // jeden einzelnen Flügel berechnen und darstellen
    Begin
        SektorWinkel:=360/Anzfluegel *i; // Winkel der einzelnen Flügel berechnen
        Sektorwinkel:=Sektorwinkel+GradZahl; // Irgendwann soll sich das Windrad ja drehen
        If SektorWinkel > 360 then Sektorwinkel:=Sektorwinkel-360; // wir bleiben bei 360 ° Kreis
        Kreispunkt :=EndPunkt(StrToInt(Ed_Fluegellaenge.Text),Sektorwinkel,Nabe); // separater Aufruf schafft Durchblick
        ShowFluegel(Nabe, Kreispunkt, ClGreen); // erst mal unsichtbar......
    End; // I-Schleife
    Gradzahl:=Gradzahl+1; // Gradzahl erhöhen, >1 wird die Drehung schneller
    If GradZahl>360 then GradZahl:=1; // auf 360° begrenzen
    For i:=1 to AnzFluegel do // und jeden einzelnen Flügel berechnen und darstellen
    Begin
        SektorWinkel:=360/Anzfluegel *i; // Winkel der einzelnen Flügel berechnen
        Sektorwinkel:=Sektorwinkel+GradZahl; // Irgendwann soll sich das Windrad ja drehen
        If SektorWinkel > 360 then Sektorwinkel:=Sektorwinkel-360; // wir bleiben bei 360 ° Kreis
        Kreispunkt :=EndPunkt(StrToInt(Ed_Fluegellaenge.Text),Sektorwinkel,Nabe);
       ShowFluegel(Nabe, Kreispunkt, ClRed); // jetzt sichtbar......
    End; // I-Schleife

End;
Nun kannst du mit Tastendrücken schrittweise prüfen, ob alles klappt. Ist es nach deinem Geschmack geraten, kannst du an die Automatisierung gehen. Nimm einen Timer und kopiere dein Button-Ereignisprogramm mit den Variablen hinein. Die Zuweisung der AnzFluegel-Variable löschst du im Timer Ereignis und im Button-Ereignis löscht du alles außer der Zuweisung der AnzFluegel-Variable.
Feddisch........

Noch mal eine kurze Bemerkung zu fogenden Zeilen

Delphi-Quellcode:
Kreispunkt :=EndPunkt(StrToInt(Ed_Fluegellaenge.Text),Sektorwinkel,Nabe); // separater Aufruf schafft Durchblick
ShowFluegel(Nabe, Kreispunkt, ClGreen); // erst mal unsichtbar......
Das geht auch ....
ShowFluegel(Nabe, EndPunkt(StrToInt(Ed_Fluegellaenge.Text), Sektorwinkel, Nabe), ClGreen); Kreispunkt wird mit dem Funktionsaufruf ersetzt und erspart die Variable „Kreispunkt“
Ist aber schlecht zu Kommentieren und für Anfänger nicht
Gruß oldmax
Noch ist mein Rechner mir zu Diensten.... ansonsten habe ich die Macht ihn zu vernichten !
  Mit Zitat antworten Zitat
shmia

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

Re: Windmühle, bei der die Flügelanzahl variabel ist

  Alt 29. Okt 2007, 12:51
Ich würde dringend empfehlen, folgende Funktionen zu verwenden:
Drehung und Verschiebung im 2D Raum
Damit wird das Zeichnen eines Flügels stark vereinfacht.
1.) ein Flügel ist ein Polygon und wird mit Canvas.Polygon(Points: array of TPoint) gezeichnet
2.) die Punkte des Flügel werden auf Karopapier so gezeichnet, dass der Drehpunkt auf (0,0) liegt
3.) jetzt braucht es 2 Operationen, um einen Flügel in beliebiger Richtung und Position zu zeichen
4.) mit Rotate2Darray() werden alle Punkte um den vorgegebenen Winkel gedreht
5.) mit Translate2Darray() wird der Drehpunkt des Flügels (der ja noch immer bei (0,0) liegt)
in den Drehpunkt der Windmühle verschoben

Diese Vorgehensweise hat viele Vorteile:
* wiederverwendbar (taugt auch für Games, Spielkarten, ...)
* flexibel (das Flügelprofil in Schritt 2.) kann völlig frei gestaltet werden)
* sauber gekapselt (die ganze Mathematik liegt in Rotate2Darray() & Translate2Darray())
* mit etwas Zusatzaufwand kann man die ganze Zeichnung auch zoomen
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von spox
spox

Registriert seit: 23. Sep 2007
47 Beiträge
 
Delphi 7 Personal
 
#10

Re: Windmühle, bei der die Flügelanzahl variabel ist

  Alt 11. Nov 2007, 15:54
So ... sry, dass ich erst jetzt antworte, aber mein Internet hat gestreikt

Ich habe es jetzt geschafft, die Flügel zu zeichnen, sodass sie in dem richtigen Winkel zueinander stehen. Doch wie könnte es anders sein: Die Drehung scheint noch nicht zu klappen... Die Idee zu der Drehung die ich hatte: die Mühleprozedur in eine TimerRoutine und dann mit Weiß übermalen. Danach den Winkel verändern und mit Schwarz malen. Danach wieder mit weiß, usw.

Doch wie verändere ich den Winkel? Ich habe das Bogenmaß 2 pi genommen. Jetzt wollte ich einfach in der zeichenRoutine um ein Grad addieren. Doch es will nicht:

Delphi-Quellcode:
unit muehleU;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

const
 pi=3.1415;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Image1: TImage;
    Edit1: TEdit;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    Timer1: TTimer;
    Button6: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Muehle(anzahl,hoehe,x,y:integer);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  v:integer;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var z:integer;
begin
 z:= StrToInt(Edit1.Text);
 Muehle (z,150,50,50);
end;

procedure TForm1.Muehle (anzahl,hoehe,x,y:integer);
var flange,nr,x2,y2,FluegelEndeX,FluegelEndeY:integer;
begin
 with Image1.Canvas do
  begin
   moveTo (x,y);
   rectangle (x,y,x+round(hoehe/5),hoehe);
   moveTo (x+(round(hoehe/5)DIV 2),y+10);
   x2:= x+(round(hoehe/5)DIV 2);
   y2:= y+10;
   flange:= hoehe DIV 2 ;
   for nr:= 1 to anzahl do
   begin
    FluegelEndeX:= x2+round(flange*cos(nr*(2*pi+v)/anzahl));
    FluegelEndeY:= y2+round(flange*sin(nr*(2*pi+v)/anzahl));
    lineTo (FluegelEndeX,FluegelEndeY);
    moveTo (x2,y2);
   end;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 Muehle (2,150,50,50);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
 Muehle (8,150,50,50);
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
 Muehle (20,150,50,50);
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
 Muehle (150,150,50,50);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
 Image1.Canvas.Pen.Color:= clBlack;
 Muehle (8,150,50,50);
 Image1.Canvas.Pen.Color:= clWhite;
 Muehle (8,150,50,50);
 Image1.Canvas.Pen.Color:= clBlack;
 Muehle (8,150,50,50);
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
Timer1.Enabled:= true;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
v:= 0
end;

end.
Ich hoffe ihr wollt mir noch helfen. Schließlich hab ich mich ja nicht gemeldet
  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 06:58 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