Obrót obiektu wokół własnej osi po elipsie

0

Mam sobie kwadracik narysowany wektorowo (wyznaczam 4 wierzchołki, które potem ze sobą łączę prostymi liniami). Napisałem algorytm obracający ten kwadrat wokół własnej osi:

  1. Dla każdego z wierzchołków (oznaczanych w układzie współrzędnych jako X,Y) odczytuję jego kąt nachylenia względem osi obrotu (czyli środka kwadratu).
function ReadAngle(Center, Point: TPoint): Real;
var
  Distance: TPoint;

begin
  Distance.X:= Point.X - Center.X;
  Distance.Y:= Point.Y - Center.Y;

  Result:= RadToDeg(ArcTan2(Distance.Y, Distance.X));
  if Result < 0 then Result:= Result + 360;

Gdzie:

  • Point.X i Point.Y to położenie punktu, którego kąt chcę odczytać.
  • Center.X i Center.Y to współrzędne środka kwadratu (osi obrotu).
  1. Liczę odległość wierzchołka względem osi obrotu (używając twierdzenia Pitagorasa):
function ReadDistance(PointA, PointB: TPoint): Real;
begin
  Result:= SQRT(SQR(PointB.X - PointA.X) + SQR(PointB.Y - PointA.Y));
end; 
  1. Mając kąt i odległość, mogę wyznaczyć nowe położenie wierzchołka:
function SetPointByAngle(Center: TPoint; Distance, Angle: Real): TPoint;

begin
  Result.X:= Center.X + Round(Distance * Cos(DegToRad(Angle)));
  Result.Y:= Center.Y + Round(Distance * Sin(DegToRad(Angle)));
end;

Gdzie:

  • Center.X i Center.Y to współrzędne środka kwadratu (osi obrotu).
  • Distance.X i Distance.Y to stała odległość wierzchołka względem osi obrotu.
  • Angle to oczywiście kąt.

Całość generalnie działa tak jak powinna (kwadrat obraca się wokół własnej osi). Ja chciałbym jednak zmodyfikować to tak, by ruch następował nie z uwzględnieniem stałej odległości wierzchołków względem osi obrotu (czyli po okręgu), lecz ze zmienną odległością (po elipsie).

Powiedzmy, że mam elipsę o wymiarach:

wysokość: 200
szerokość: 400

Odczytuję sobie odległość wierzchołka nr 1 względem osi obrotu, oraz jego kąt nachylenia względem całego układu (powiedźmy odległość 100 i kąt 90). Wyznaczam nowy kąt (np. 180) i nowe położenie wierzchołka. Jako że chcę, aby wierzchołek został wyznaczony na elipsie, nie mogę po prostu użyć oryginalnej odległości (100).

Tutaj oczywiście sprawa jest prosta, bo wiem dokładnie, że przy kątach 0 i 180 stopni, odległość od środka do krawędzi elipsy wynosi 200. Co jednak z pozostałymi kątami, np. 63 albo 174?

Proszę o jakąś podpowiedź.

0

Zobacz tutaj - https://forum.processing.org/one/topic/move-elements-along-the-ellipse-path.html

Kod co prawda napisany jest w C++, jednak nie powinieneś mieć problemu z jego przeportowaniem.

1

Rozgryzłem to i podaję rozwiązanie dla potomności.

Trzeba zmodyfikować funkcję:

function SetPointByAngle(Center: TPoint; Distance, Angle: Real): TPoint;
begin
  Result.X:= Center.X + Round(Distance * Cos(DegToRad(Angle)));
  Result.Y:= Center.Y + Round(Distance * Sin(DegToRad(Angle)));
end; 

i zamiast stałego Distance (równego odległości badanego wierzchołka od środka kwadratu), należy podawać osobną wartość dla współrzędnej X i osobną dla Y, podstawiając tam odpowiednio szerokość (dla X) i wysokość (dla Y) elipsy, dzielone przez 2 (czyli taki jakby "promień elipsy").

1 użytkowników online, w tym zalogowanych: 0, gości: 1