Saya mencoba membuat permainan kartu di mana kartu menyebar. Sekarang untuk menampilkannya saya menggunakan Allegro API yang memiliki fungsi:
al_draw_rotated_bitmap(OBJECT_TO_ROTATE,CENTER_X,CENTER_Y,X
,Y,DEGREES_TO_ROTATE_IN_RADIANS);
jadi dengan ini saya bisa membuat efek kipas saya dengan mudah. Masalahnya adalah mengetahui kartu mana yang ada di bawah mouse. Untuk melakukan ini, saya berpikir untuk melakukan tes tabrakan poligon. Saya hanya tidak yakin bagaimana memutar 4 titik pada kartu untuk membentuk poligon. Saya pada dasarnya perlu melakukan operasi yang sama seperti Allegro.
Misalnya, 4 poin dari kartu tersebut adalah:
card.x
card.y
card.x + card.width
card.y + card.height
Saya membutuhkan fungsi seperti:
POINT rotate_point(float cx,float cy,float angle,POINT p)
{
}
Terima kasih
Jika Anda memutar titik di
(px, py)
sekitar titik(ox, oy)
demi sudut, Anda akan mendapatkan:p'x = cos(theta) * (px-ox) - sin(theta) * (py-oy) + ox
p'y = sin(theta) * (px-ox) + cos(theta) * (py-oy) + oy
ini adalah cara mudah untuk memutar titik dalam 2D.
sumber
ox
danoy
ditambahkan kembali di akhir setiap baris.Sistem koordinat pada layar adalah kidal, yaitu koordinat x bertambah dari kiri ke kanan dan koordinat y bertambah dari atas ke bawah. Asal, O (0, 0) ada di sudut kiri atas layar.
Sebuah searah jarum jam rotasi di sekitar asal dari titik dengan koordinat (x, y) diberikan oleh persamaan berikut:
dimana (x ', y') adalah koordinat titik setelah rotasi dan sudut theta, sudut rotasi (perlu dalam radian, yaitu dikalikan dengan: PI / 180).
Untuk melakukan rotasi di sekitar titik yang berbeda dari titik asal O (0,0), katakanlah titik A (a, b) (titik pivot). Pertama kita terjemahkan titik yang akan diputar, yaitu (x, y) kembali ke asalnya, dengan mengurangkan koordinat titik pivot, (x - a, y - b). Kemudian kami melakukan rotasi dan mendapatkan koordinat baru (x ', y') dan akhirnya kami menerjemahkan kembali titik tersebut, dengan menambahkan koordinat titik pivot ke koordinat baru (x '+ a, y' + b).
Berikut uraian di atas:
Rotasi 2D searah jarum jam theta derajat titik (x, y) disekitar titik (a, b) adalah:
Menggunakan prototipe fungsi Anda: (x, y) -> (px, py); (a, b) -> (cx, cy); theta -> sudut:
POINT rotate_point(float cx, float cy, float angle, POINT p){ return POINT(cos(angle) * (p.x - cx) - sin(angle) * (p.y - cy) + cx, sin(angle) * (p.x - cx) + cos(angle) * (p.y - cy) + cy); }
sumber
float s = sin(angle); // angle is in radians float c = cos(angle); // angle is in radians
Untuk rotasi searah jarum jam:
float xnew = p.x * c + p.y * s; float ynew = -p.x * s + p.y * c;
Untuk rotasi berlawanan arah jarum jam:
float xnew = p.x * c - p.y * s; float ynew = p.x * s + p.y * c;
sumber
c
dans
?c = cos(angle)
Ini adalah jawaban dari Nils Pipenbrinck, tetapi diimplementasikan dalam c # fiddle.
https://dotnetfiddle.net/btmjlG
using System; public class Program { public static void Main() { var angle = 180 * Math.PI/180; Console.WriteLine(rotate_point(0,0,angle,new Point{X=10, Y=10}).Print()); } static Point rotate_point(double cx, double cy, double angle, Point p) { double s = Math.Sin(angle); double c = Math.Cos(angle); // translate point back to origin: p.X -= cx; p.Y -= cy; // rotate point double Xnew = p.X * c - p.Y * s; double Ynew = p.X * s + p.Y * c; // translate point back: p.X = Xnew + cx; p.Y = Ynew + cy; return p; } class Point { public double X; public double Y; public string Print(){ return $"{X},{Y}"; } } }
Ps: Ternyata saya tidak bisa berkomentar, jadi wajib saya posting sebagai jawaban ...
sumber