किसी अन्य बिंदु (2D) के बारे में एक बिंदु को घुमाना


139

मैं एक कार्ड गेम बनाने की कोशिश कर रहा हूं, जहां कार्ड फैन आउट होंगे। अभी इसे Allegro API का उपयोग करके Im प्रदर्शित करना है जिसमें एक फ़ंक्शन है:

al_draw_rotated_bitmap(OBJECT_TO_ROTATE,CENTER_X,CENTER_Y,X
        ,Y,DEGREES_TO_ROTATE_IN_RADIANS);

इसलिए इसके साथ मैं अपने प्रशंसक प्रभाव को आसानी से बना सकता हूं। समस्या तो यह है कि माउस के नीचे कौन सा कार्ड है। ऐसा करने के लिए मैंने एक बहुभुज टक्कर परीक्षण करने के बारे में सोचा। मुझे यकीन नहीं है कि बहुभुज बनाने के लिए कार्ड पर 4 बिंदुओं को कैसे घुमाया जाए। मुझे मूल रूप से Allegro के समान ऑपरेशन करने की आवश्यकता है।

उदाहरण के लिए, कार्ड के 4 बिंदु हैं:

card.x

card.y

card.x + card.width

card.y + card.height

मुझे एक फ़ंक्शन की आवश्यकता होगी जैसे:

POINT rotate_point(float cx,float cy,float angle,POINT p)
{
}

धन्यवाद

जवाबों:


331

पहले धुरी बिंदु को घटाएं (cx,cy), फिर इसे घुमाएं, फिर बिंदु को फिर से जोड़ें।

untested:

POINT rotate_point(float cx,float cy,float angle,POINT p)
{
  float s = sin(angle);
  float c = cos(angle);

  // translate point back to origin:
  p.x -= cx;
  p.y -= cy;

  // rotate point
  float xnew = p.x * c - p.y * s;
  float ynew = p.x * s + p.y * c;

  // translate point back:
  p.x = xnew + cx;
  p.y = ynew + cy;
  return p;
}

45
बहुत बढ़िया जवाब। रिकॉर्ड के लिए, आपको रोटेशन सही पहली बार मिला।
n.collins

@ साइनक्राइज़र बिल्कुल समान है, बस रोटेशन के लिए अपने बिंदु घटाव / जोड़ दिनचर्या और अपने वेक्टर * मैट्रिक्स फ़ंक्शन का उपयोग करें।
निल्स पिपेनब्रिंक

8
यह बताने के लिए अनिच्छुक के लिए सहायक हो सकता है कि पाप और कॉस कोण को रेडियन में व्यक्त किए जाने की उम्मीद कर सकते हैं।
15ee8f99-57ff-4f92-890c-b56153

72

यदि आप कोण से बिंदु को (px, py)चारों ओर घुमाते हैं, (ox, oy)तो आपको मिलेगा:

p'x = cos(theta) * (px-ox) - sin(theta) * (py-oy) + ox

p'y = sin(theta) * (px-ox) + cos(theta) * (py-oy) + oy

यह 2 डी में एक बिंदु को घुमाने का एक आसान तरीका है।


7
आपको रोटेशन के बाद वापस अनुवाद करने की आवश्यकता है। इसलिए समाधान होगा: p'x + = ox
hAlE

57

स्क्रीन पर समन्वय प्रणाली बाएं हाथ से है, यानी x निर्देशांक बाएं से दाएं बढ़ता है और y निर्देशांक ऊपर से नीचे तक बढ़ता है। मूल, O (0, 0) स्क्रीन के ऊपरी बाएं कोने पर है।

यहां छवि विवरण दर्ज करें

निर्देशांक (x, y) के साथ एक बिंदु के मूल के चारों ओर एक दक्षिणावर्त घुमाव निम्नलिखित समीकरणों द्वारा दिया गया है:

यहां छवि विवरण दर्ज करें

जहां (x ', y') रोटेशन और कोण थीटा के बाद बिंदु के निर्देशांक हैं, रोटेशन के कोण (रेडियन में होने की आवश्यकता है, यानी गुणा: पीआई / 180)।

मूल O (0,0) से भिन्न बिंदु के चारों ओर घूमने के लिए, मान लीजिए कि बिंदु A (a, b) (धुरी बिंदु) है। सबसे पहले हम बिंदु को घुमाए जाने के लिए अनुवाद करते हैं, यानी (x, y) मूल में वापस आते हैं, धुरी बिंदु के निर्देशांक को घटाकर, (x - a, y - b)। तब हम रोटेशन करते हैं और नए निर्देशांक (x ', y') प्राप्त करते हैं और अंत में हम नए निर्देशांक (x '+ a, y' + b) के लिए धुरी बिंदु के निर्देशांक जोड़कर बिंदु को वापस अनुवाद करते हैं।

उपरोक्त विवरण के बाद:

बिंदु (ए, बी) के चारों ओर बिंदु ( x, y) का एक 2D क्लॉकवाइज थीटा डिग्री रोटेशन है:

अपने फ़ंक्शन प्रोटोटाइप का उपयोग करना: (x, y) -> (px, py); (ए, बी) -> (सीएक्स, साइबर); थीटा -> कोण:

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);
}

29
float s = sin(angle); // angle is in radians
float c = cos(angle); // angle is in radians

दक्षिणावर्त रोटेशन के लिए:

float xnew = p.x * c + p.y * s;
float ynew = -p.x * s + p.y * c;

काउंटर दक्षिणावर्त रोटेशन के लिए:

float xnew = p.x * c - p.y * s;
float ynew = p.x * s + p.y * c;

क्या है cऔर s?
टैंकरस्मैश

1
@TankorSmash को इसके ऊपर परिभाषित किया गयाc = cos(angle)
nycynik

2

यह निल्स पिपेनब्रिनक का उत्तर है, लेकिन सी # फिडल में लागू किया गया है।

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: जाहिरा तौर पर मैं टिप्पणी नहीं कर सकता, इसलिए मैं इसे उत्तर के रूप में पोस्ट करने के लिए बाध्य हूं ...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.