AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Cross-Platform-Entwicklung iOS Trägheitsberechnung bei Gestures
Thema durchsuchen
Ansicht
Themen-Optionen

Trägheitsberechnung bei Gestures

Ein Thema von Union · begonnen am 8. Nov 2013 · letzter Beitrag vom 8. Nov 2013
Antwort Antwort
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#1

Trägheitsberechnung bei Gestures

  Alt 8. Nov 2013, 09:51
Das Thema betrifft auch Android.

Da in Firemonkey die Trägheit von Bewegungen bei der Verarbeitung von Gesten auf den mobilen Plattformen nicht unterstützt wird, muß man sich das ja zwangsweise selber schreiben. Hat da jemand was Fertiges? Ich habe zwar Ansätze, stoße aber immer wieder auf Sonderfälle.

Verarbeitung im Gesturevent beim Panning:
  • Im gfbegin - Merken der aktuellen Position und Zeit
  • Im gfEnd - Errechnen der Distanz aus der aktuellen und gemerkten Position für jede Achse
  • Errechnen der Geschwindigkeiten aus den Distanzen und der verstrichenen Zeit
  • Bei Überschreiten eines Grenzwertes eine FloatAnimation für jede Achse ausführen mit atOut und itQuadratic
Was mir daran nicht gefällt (bei meinen Prototyp-Versuchen jedenfalls) ist, dass man für das Merken der Werte globale Variablen hat. Spätestens wenn man ZWEI GestureEvents im gleichen Formular verwendet wird das unangenehm.
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Darlo

Registriert seit: 28. Jul 2008
Ort: München
1.196 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#2

AW: Trägheitsberechnung bei Gestures

  Alt 8. Nov 2013, 15:06
Was mir daran nicht gefällt (bei meinen Prototyp-Versuchen jedenfalls) ist, dass man für das Merken der Werte globale Variablen hat. Spätestens wenn man ZWEI GestureEvents im gleichen Formular verwendet wird das unangenehm.
So habe ich es auch, funktioniert. Wollte zuerst den Tag des Objektes missbrauchen, fand das aber auch nicht schöner....
Philip
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#3

AW: Trägheitsberechnung bei Gestures

  Alt 8. Nov 2013, 18:56
Ich habe das Fehlen der Verarbeitung der Trägheitswerte gemeldet.

So sieht meine OnGesture momentan aus (gezeichnet wird asynchron abhängig von NeedsPaint damit man performant zoomen kann):
Delphi-Quellcode:
public
    StartDistance : integer;
    StartLocation : TPointF;
    StartPos : TPointF;
    LastZoomed : TDateTime;
    LastPanned : TDateTime;
    NeedsPaint : Boolean;
    CursorCircle : TCircle;
end;

procedure TForm1.Layout1Gesture(Sender: TObject;
  const EventInfo: TGestureEventInfo; var Handled: Boolean);
var
  Factor : double;
  NewScale : double;
  Speed : TPointF;
  Distance : TPointF;
begin
  if EventInfo.GestureID = igiZoom then
  begin
    if TInteractiveGestureFlag.gfBegin in EventInfo.Flags then
       StartDistance := EventInfo.Distance
    else
    begin
      Factor := EventInfo.Distance / StartDistance;
      if (Factor > 0.04) or (Factor < -0.04) then
      begin
        NewScale := Painter.Scale * Factor;
        if NewScale > MaxScale then
          NewScale := MaxScale;
        if (NewScale <= MaxScale) and (NewScale > 0.5) then
        begin
          Painter.Scale := NewScale;
          Imagecontrol1.Scale.X := NewScale/Painter.PaintedScale*Factor;
          Imagecontrol1.Scale.Y := NewScale/Painter.PaintedScale*Factor;
          CursorCircle.Scale.X := Painter.Scale;
          CursorCircle.Scale.Y := Painter.Scale;
          LastZoomed := Now;
          NeedsPaint := True;
        end;
      end;
      StartDistance := EventInfo.Distance;
    end;
  end
  else
  if Eventinfo.GestureID = igiDoubleTap then
  begin
    ShowMessage(Format('IW: %f BW: %d', [Imagecontrol1.Width, Painter.Bitmap.Width]));
  end
  else
  if EventInfo.GestureID = igiPan then
  begin
    // Um zu verhindern dass beim Beenden einer Zoomoperation die Bewegung des
    // zuletzt angehobenen Fingers als Bewegungswunsch angesehen wird.
    if MilliSecondsBetween(Now, LastZoomed) > 100 then
    begin
      if TInteractiveGestureFlag.gfBegin in EventInfo.Flags then
      begin
         StartLocation := EventInfo.Location;
         StartPos := EventInfo.Location;
         LastPanned := Now;
      end
      else
      if TInteractiveGestureFlag.gfEnd in EventInfo.Flags then
      begin
        Factor := MSecsPerDay*(Now-LastPanned);
        Distance.X := EventInfo.Location.X-StartPos.X;
        Distance.Y := EventInfo.Location.Y-StartPos.Y;
        Speed.X := Distance.X / Factor;
        Speed.Y := Distance.Y / Factor;
        AdjustPosition(Speed);
      end
      else
      begin
        ImageControl1.Position.X := ImageControl1.Position.X + (EventInfo.Location.X - StartLocation.X);
        ImageControl1.Position.Y := ImageControl1.Position.Y + (EventInfo.Location.Y - StartLocation.Y);
        Speed.X := 0;
        Speed.Y := 0;
        AdjustPosition(Speed);
        StartLocation := EventInfo.Location;
      end;
    end;
  end;
end;

procedure TForm1.AdjustPosition(ASpeed : TPointF);
begin
  // Trägheit simulieren
  if abs(ASpeed.X) > 1 then
     ImageControl1.AnimateFloat('Position.X', Imagecontrol1.Position.X+50*ASpeed.X, 0.5, TAnimationType.atOut, TInterpolationType.itQuadratic);
  if abs(ASpeed.Y) > 1 then
     ImageControl1.AnimateFloat('Position.Y', Imagecontrol1.Position.Y+50*ASpeed.Y, 0.5, TAnimationType.atOut, TInterpolationType.itQuadratic);

  // Ggf. Bounceback wenn zu nah an den Rand bewegt
  if ImageControl1.Position.X+(Imagecontrol1.Width/2) < 50 then
     ImageControl1.AnimateFloat('Position.X', 100-(Imagecontrol1.Width/2), 0.3)
  else
  if ImageControl1.Position.X > Layout1.Width -50 then
    Imagecontrol1.AnimateFloat('Position.X', Layout1.Width-100, 0.3);

  if ImageControl1.Position.Y+(Imagecontrol1.Height/2) < 50 then
     ImageControl1.AnimateFloat('Position.Y', 100-(Imagecontrol1.Height/2), 0.3)
  else
  if ImageControl1.Position.Y > Layout1.Height -50 then
    Imagecontrol1.AnimateFloat('Position.Y', Layout1.Height-100, 0.3);
end;
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Antwort Antwort


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 07:18 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