سؤال

لدي معادلة لمنحنى مكافئ يتقاطع مع نقطة محددة، في حالتي حيث نقر المستخدم على الرسم البياني.

 // this would typically be mouse coords on the graph
 var _target:Point = new Point(100, 50);

 public static function plot(x:Number, target:Point):Number{
  return (x * x) / target.x * (target.y / target.x);
 }

وهذا يعطي رسم بياني مثل هذا:

parabolic curve

لدي أيضًا سلسلة من المقاطع الخطية المحددة بإحداثيات البداية والنهاية:

startX:Number, startY:Number, endX:Number, endY:Number

أحتاج إلى معرفة ما إذا كان هذا المنحنى يتقاطع مع هذه الأجزاء (أ) وأين:

alt text

إذا كان هناك أي مساعدة، startX دائما < endX

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

تحديث:

لقد نجح التقاطع، لكن الحل الذي توصلت إليه يعطيني الإحداثيات للجانب الخاطئ من المحور الصادي.

استبدال إحداثياتي المستهدفة بـ A وB على التوالي، يعطي هذه المعادلة للمخطط:

(x * x) / A * (B/A)

// this simplifies down to:
(B * x * x) / (A * A)

// which i am the equating to the line's equation
(B * x * x) / (A * A) =  m * x + b

// i run this through wolfram alpha (because i have no idea what i'm doing) and get:
(A * A * m - A * Math.sqrt(A * A * m * m + 4 * b * B)) / (2 * B)

هذا يكون إجابة صحيحة، ولكن أريد البديل الثاني المحتمل.لقد تمكنت من تصحيح هذا عن طريق ضرب m في -1 قبل الحساب والقيام بنفس الشيء مع قيمة x التي أعادتها العملية الحسابية الأخيرة، ولكن هذا يبدو وكأنه اختراق.

حل:

 public static function intersectsSegment(targetX:Number, targetY:Number, startX:Number, startY:Number, endX:Number, endY:Number):Point {
  // slope of the line
  var m:Number = (endY - startY) / (endX - startX);

  // where the line intersects the y-axis
  var b:Number = startY - startX * m;

  // solve the two variatons of the equation, we may need both
  var ix1:Number = solve(targetX, targetY, m, b);
  var ix2:Number = solveInverse(targetX, targetY, m, b);

  var intersection1:Point;
  var intersection2:Point;

  // if the intersection is outside the line segment startX/endX it's discarded
  if (ix1 > startX && ix1 < endX) intersection1 = new Point(ix1, plot(ix1, targetX, targetY));
  if (ix2 > startX && ix2 < endX) intersection2 = new Point(ix2, plot(ix2, targetX, targetY));

  // somewhat fiddly code to return the smallest set intersection
  if (intersection1 && intersection2) {
   // return the intersection with the smaller x value
   return intersection1.x < intersection2.x ? intersection1 : intersection2;
  } else if (intersection1) {
   return intersection1;
  }

  // this effectively means that we return intersection2 or if that's unset, null
  return intersection2;
 }

 private static function solve(A:Number, B:Number, m:Number, b:Number):Number {
  return (m + Math.sqrt(4 * (B / (A * A)) * b + m * m)) / (2 * (B / (A * A)));
 }

 private static function solveInverse(A:Number, B:Number, m:Number, b:Number):Number {
  return (m - Math.sqrt(4 * (B / (A * A)) * b + m * m)) / (2 * (B / (A * A)));
 }

 public static function plot(x:Number, targetX:Number, targetY:Number):Number{
  return (targetY * x * x) / (targetX * targetX);
 }
هل كانت مفيدة؟

المحلول

أو أكثر وضوحا حتى الآن.

إذا كان منحنى مكافئك y(x)= A x2+ B x + C (Eq 1)

وخطك هو y(x) = m x + b (Eq 2)

الحلان الممكنان (+ و -) لـ X هما

x = ((-B + m +- Sqrt[4 A b + B^2 - 4 A C - 2 B m + m^2])/(2 A))   (Eq 3)

يجب عليك التحقق مما إذا كانت نقاط النهاية الخاصة بك (في X) تحتوي على أي من هاتين النقطتين. إذا فعلوا ذلك ، فما عليك سوى استبدال x المقابلة في معادلة y = mx + b للحصول على إحداثي y للتقاطع

تحرير>

للحصول على المعادلة الأخيرة ، تقول فقط إن "Y" في Eq 1 يساوي "Y" في Eq 2 (لأنك تبحث عن تقاطع!). هذا يمنحك:

A x2+ B x + C = m x + b

وإعادة تجميع

A x2+ (B-m) x + (C-b) = 0

وهي معادلة تربيعية.

المعادلة 3 هي مجرد الحللين الممكنين لهذا التربيعي.

تحرير 2>

إعادة قراءة التعليمات البرمجية الخاصة بك ، يبدو أن المكافئ الخاص بك محدد بواسطة y(x) = A x2

أين
A = (target.y / (target.x)2)

لذلك في قضيتك يصبح Eq 3 ببساطة

 x = ((m +- Sqrt[4 A b + m^2])/(2 A))   (Eq 3b)  

هول!

نصائح أخرى

خذ المعادلة للمنحنى ووضع خطك في نموذج y = mx +b. قم بحل X ثم حدد ما إذا كان X بين نقاط البدء والنهاية الخاصة بك لقطاع الخط.

الدفع: http://mathcentral.uregina.ca/qq/database/qq.09.03/senthil1.html

هل تفعل هذا كثيرًا بما يكفي للرغبة في إجراء اختبار منفصل لمعرفة ما إذا كان هناك تقاطع قبل حساب نقطة التقاطع فعليًا؟إذا كان الأمر كذلك، ففكر في حقيقة أن القطع المكافئ الخاص بك هو مستوى محدد للدالة f(x, y) = y - (B * x * x) / (A * A) - على وجه التحديد، الدالة التي f(x, ص) = 0.قم بتوصيل نقطتي النهاية في f(x,y) -- إذا كان لهما نفس الإشارة، فهما على نفس الجانب من القطع المكافئ، بينما إذا كان لهما إشارات مختلفة، فهما على جانبين مختلفين من القطع المكافئ.

الآن، لا يزال لديك قطعة تتقاطع مع القطع المكافئ مرتين, ، وهذا الاختبار لا يلتقط ذلك.ولكن شيئًا ما يتعلق بالطريقة التي تحدد بها المشكلة يجعلني أشعر أنه ربما يكون هذا أمرًا جيدًا بالنسبة لتطبيقك.

بمعنى آخر ، تحتاج إلى تخصيص المعادلة لكل مقطع خط y = Ax + B قارنها لمنحنى المعادلة y = Cx^2 + Dx + E لذا Ax + B - Cx^2 - Dx - E = 0 ومعرفة ما إذا كان هناك حل بين startX و endX القيم.

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