Einzelnen Beitrag anzeigen

Wheelie

Registriert seit: 21. Okt 2003
Ort: Dresden
177 Beiträge
 
#1

(realistische) Dämpfung eines Pendels

  Alt 5. Jul 2004, 10:41
Wie einige schon wissen, entwickle ich für eine kleine Belegarbeit eine grafische Pendelkomponente zur Simulation eines mathematischen Pendels. Dabei habe ich mich an Luckie's Pendelsimulation orientiert ... Danke schonmal an Luckie

Nun möchte ich die reale Pendeldämpfung bei maximaler Auslenkung entwickeln, finde dazu aber überhaupt keinen Ansatz.

Hier der bisherige Quelltext:
Delphi-Quellcode:
unit Pendel;

interface

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

type
  TPendel = class(TCustomControl)
  private
    { Private-Deklarationen }

    Timer: TTimer;
    Bitmap: TBitmap;

    Winkel, PendelLaenge: Integer;
    PendelLinks: Boolean;

    procedure TimerOnTimer(Sender: TObject);
    procedure PendelZeichnen(Winkel: Integer);

  protected
    { Protected-Deklarationen }

  public
    { Public-Deklarationen }

    constructor Create(AOwner: TComponent); override;
    procedure Paint; override;
    function Gegenkathete(Winkel: Integer): Real;
    function Ankathete(Winkel: Integer): Real;

  published
    { Published-Deklarationen }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Pendel', [TPendel]);
end;

function TPendel.Gegenkathete(Winkel: Integer): Real;
begin
  Result := Sin(DegToRad(Winkel)) * PendelLaenge;
end;

function TPendel.Ankathete(Winkel: Integer): Real;
begin
  Result := Cos(DegToRad(Winkel)) * PendelLaenge;
end;

constructor TPendel.Create;
begin
  inherited Create(AOwner);

  if Width = 0 then Width := 300;
  if Height = 0 then Height := 250;

  Bitmap := TBitmap.Create;

  Timer := TTimer.Create(Self);
  Timer.Interval := 50;
  Timer.OnTimer := TimerOnTimer;
  Timer.Enabled := True;
end;

procedure TPendel.TimerOnTimer(Sender: TObject);
begin
  if (Width <> Bitmap.Width) or (Height <> Bitmap.Height) then
  begin
    Bitmap.Width := Width;
    Bitmap.Height := Height;
    PendelLaenge := Height - 50;
  end;

  if not PendelLinks then Inc(Winkel)
   else Dec(Winkel);

  if Winkel = 30 then PendelLinks := True;
  if Winkel = -30 then PendelLinks := False;

  Paint;
end;

procedure TPendel.PendelZeichnen(Winkel: Integer);
begin
  Bitmap.Canvas.MoveTo(Width div 2, 25);

  // Pendelfaden
  Bitmap.Canvas.LineTo(Width div 2 + Round(Gegenkathete(Winkel)),
    Round(Ankathete(Winkel)));

  // Pendelkörper
  Bitmap.Canvas.Brush.Color := clBlack;
  Bitmap.Canvas.Brush.Style := bsSolid;
  Bitmap.Canvas.Ellipse(Width div 2 + Round(Gegenkathete(Winkel))
    - 20, Round(Ankathete(Winkel)) - 20, Width div 2 +
    Round(Gegenkathete(Winkel)) + 20, Round(Ankathete(Winkel)) + 20);
end;

procedure TPendel.Paint;
begin
  inherited Paint;

  // Pendel auf Bitmap im Speicher zeichnen
  PendelZeichnen(Winkel);

  // Bitmap auf Canvas der Komponente kopieren
  BitBlt(Canvas.Handle, 0, 0, Width, Height,
    Bitmap.Canvas.Handle, 0, 0, SRCCOPY);

  // Bitmap mit weiß überschreiben
  Bitmap.Canvas.Brush.Color := clWhite;
  Bitmap.Canvas.Rectangle(0, 0, Width, Height);
  Bitmap.Canvas.Brush.Color := clBlack;
end;

end.
Tatsache ist, dass das Intervall des Timers ständig geändert werden muss. Zur Berechnung fehlt mir aber irgendwie das physikalische Hintergrundwissen (), ihr könnt mir da aber bestimmt weiterhelfen
  Mit Zitat antworten Zitat