بالنظر إلى زاوية أبعاد إيجاد تنسيق على طول محيط المستطيل

StackOverflow https://stackoverflow.com/questions/1026763

  •  06-07-2019
  •  | 
  •  

سؤال

أنا أكتب سيناريو حيث الرموز تدور حول محور معين (أو الأصل).لقد كنت قادرا على جعل هذا العمل الدورية الرموز حول القطع الناقص ولكن أريد أيضا أن يتحرك حول محيط مستطيل معين والعرض والارتفاع الأصل.

أنا بهذه الطريقة لأن القانون الحالي بتخزين كافة coords في مجموعة مع بعضها زاوية عدد صحيح مثل إعادة استخدام هذا الرمز سيكون أسهل بكثير للعمل مع.

إذا كان شخص ما يمكن أن تعطيني مثالا على 100x150 مستطيل ، التي من شأنها أن تكون كبيرة.

تحرير: للتوضيح التي تدور حول أعني يتحرك حول محيط (أو المداري) شكل.

هل كانت مفيدة؟

المحلول

يمكنك أن تعرف حجم المستطيل تحتاج إلى تقسيم كل زاوية الفاصل في أربعة مختلفة ، حتى تعرف إذا كان شعاع من وسط المستطيل يتقاطع الحق, أعلى, اليسار أو أسفل المستطيل.

إذا كانت الزاوية:-atan(d/w) < الفا < atan(d/w) راي يتقاطع الجانب الأيمن من المستطيل.ومنذ ذلك الحين تعرف أن x-النزوح من وسط المستطيل إلى الجانب الأيمن هو د/2 وتشريد dy مقسوما د/2 هو تان(ألفا) ، حيث

dy = d/2 * تان(الفا)

يمكنك التعامل مع هذا وبالمثل مع الآخر ثلاثة زاوية فترات.

حسنا, هنا يذهب.لديك المستطيل مع العرض w وعمق د.في منتصف لديك نقطة المركز ، cp.افترض أنك تريد حساب ف ، من أجل قيم مختلفة من زاوية الفا.

alt text

لقد قسمت المستطيل في أربعة مجالات مختلفة ، أو زاوية فترات (1 إلى 4).الفاصل الزمني ذكرت أعلاه هو أول واحد إلى اليمين.آمل أن يكون هذا يجعل الشعور لك.

أولا تحتاج إلى حساب زاوية فترات هذه مصممون تماما من قبل ث و د. اعتمادا على ما قيمة ألفا ، حساب P تبعا لذلك ، أيإذا كان "راي" من م أ ف يتقاطع الجزء السفلي الأيمن أو الأيسر الجانبين من المستطيل.

هتافات

نصائح أخرى

وجاء هذا لوالتحقق منها للعمل على ساعة ذكية حصاة، ولكن تعديلها لتكون شبة الكود:

struct GPoint {
  int x;
  int y;
}

// Return point on rectangle edge.  Rectangle is centered on (0,0) and has a width of w and height of h
GPoint getPointOnRect(int angle, int w, int h) {
  var sine = sin(angle), cosine = cos(angle);   // Calculate once and store, to make quicker and cleaner
  var dy = sin>0 ? h/2 : h/-2;                  // Distance to top or bottom edge (from center)
  var dx = cos>0 ? w/2 : w/-2;                  // Distance to left or right edge (from center)
  if(abs(dx*sine) < abs(dy*cosine)) {           // if (distance to vertical line) < (distance to horizontal line)
    dy = (dx * sine) / cosine;                  // calculate distance to vertical line
  } else {                                      // else: (distance to top or bottom edge) < (distance to left or right edge)
    dx = (dy * cosine) / sine;                  // move to top or bottom line
  }
  return GPoint(dx, dy);                        // Return point on rectangle edge
}


Use:
rectangle_width  = 100;
rectangle_height = 150;
rectangle_center_x = 300;
rectangle_center_y = 300;
draw_rect(rectangle_center_x - (rectangle_width/2), rectangle_center_y - (rectangle_center_h/2), rectangle_width, rectangle_height);
GPoint point = getPointOnRect(angle, rectangle_width, rectangle_height);
point.x += rectangle_center_x;
point.y += rectangle_center_y;
draw_line(rectangle_center_x, rectangle_center_y, point.x, point.y);

واحد طريقة بسيطة للقيام بذلك باستخدام زاوية كمعلمة هي ببساطة مقطع X و Y القيم باستخدام حدود المستطيل. وبعبارة أخرى، حساب الموقف كما لو رمز سوف تدور حول مسار دائري أو بيضاوي الشكل، ثم تطبيق هذه:

و(على افتراض المستطيل الانحياز محور تركزت في (0،0)، مع طول X-محور XAxis وطول Y-محور YAxis):

if (X > XAxis/2)    
         X = XAxis/2;

if (X < 0 - XAxis/2)
         X = 0 - XAxis/2;

if (Y > YAxis/2)    
         Y = YAxis/2;

if (Y < 0 - YAxis/2)    
         Y = 0 - YAxis/2;

والمشكلة مع هذا النهج هو أن زاوية لن تكون دقيقة تماما وسوف السرعة على امتداد محيط المستطيل لا يكون ثابتا. النمذجة القطع الناقص الذي osculates المستطيل في أركانها يمكن أن تقلل من تأثير، ولكن إذا كنت تبحث عن نحو سلس، ثابتة السرعة "المدار" هذا الأسلوب لن تكون كافية.

إذا أعتقد أنك تقصد تدوير مثل الأرض تدور حول الشمس (وليس الدوران الذاتي...لذا السؤال هو حول كيفية الشريحة على طول حواف المستطيل؟)

إذا كنت يمكن أن تعطي هذه محاولة:

# pseudo coode
for i = 0 to 499
  if i < 100:  x++
  else if i < 250: y--
  else if i < 350: x--
  else y++

  drawTheIcon(x, y)

تحديث: (انظر التعليق أدناه)

استخدام زاوية سطر واحد سوف يكون

y / x = tan(th)       # th is the angle

خطوط أخرى بسيطة لأنها فقط أفقي أو عمودي.لذلك على سبيل المثال ، فمن x = 50 و يمكنك وضع هذا في السطر أعلاه للحصول على y.تفعل ذلك من أجل تقاطع الخط الأفقي و العمودي الخط (على سبيل المثال ، زاوية 60 درجة و النار "شمال شرق"...الآن لديك نقطتين.ثم النقطة التي هي الأقرب إلى الأصل هو الذي يضرب المستطيل الأول).

استخدام 2D مصفوفة التحويل.العديد من اللغات (مثلا ، جافا) دعم هذا أصلا (ابحث AffineTransformation);وإلا كتابة الروتينية للقيام دوران نفسك مرة واحدة ، تصحيح ذلك جيدا ، و استخدامها إلى الأبد.يجب أن يكون خمسة منهم مكتوبة بلغات مختلفة.

مرة واحدة يمكنك أن تفعل دوران ببساطة العثور على موقع على المستطيل عن طريق القيام خط-خط تقاطع.العثور على مركز تدور حول رمز من تقاطع خطين:

  1. شعاع من مركز الدوران في زاوية تريدها
  2. واحد من الجوانب الأربعة ، يحدها من زاوية ما تريد (في أربعة أجزاء).

ورسم نفسك رسم على قطعة من الورق مع مستطيل ومركز الدوران. أول ترجمة المستطيل إلى مركز في أصل تنسيق النظام الخاص بك (تذكر المعلمات الترجمة، ستحتاج إلى عكس الترجمة في وقت لاحق). وتناوب على المستطيل بحيث جوانبها موازية لمحاور (نفس السبب) تنسيق.

والآن لديك مثلث مع زاوية معروفة في الأصل، والجانب الآخر هو طول معروف (نصف طول جانب واحد من المستطيل)، ويمكنك الآن:

و- حل المثلث

و- التراجع عن دوران

و- التراجع عن الترجمة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top