ما هي أسرع طريقة للعثور على نقطة التقاطع بين الشعاع والمضلع؟

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

  •  10-07-2019
  •  | 
  •  

سؤال

تماما كما يطرح السؤال.يفضل أن تكون الإجابات برمز زائف ومرجع إليها.الإجابة الصحيحة يجب أن تعطي الأولوية للسرعة على البساطة.

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

المحلول

التقاطعات من الأشعة، قطاعات، الطائرات والمثلثات في 3D . يمكنك العثور على طرق لتثليث المضلعات.

إذا كنت حقا بحاجة راي / مضلع التقاطع، انها على 16.9 من في الوقت الحقيقي التقديم (13.8 ل الطبعة 2ND).

<اقتباس فقرة>   

ونحن أول حساب تقاطع   بين راي و[الطائرة من   المضلع] pie_p، التي يسهل القيام بها   عن طريق استبدال x من راي.

 n_p DOT (o + td) + d_p = 0 <=> t = (-d_p - n_p DOT o) / (n_p DOT d)
<اقتباس فقرة>   

وإذا كان |n_p DOT d| < epsilon القاسم، حيث epsilon صغير جدا   عدد، ثم يعتبر راي   موازية لطائرة المضلع ولا   يحدث التقاطع. وإلا فإن   نقطة التقاطع، p من راي و   يتم احتساب الطائرة المضلع: p = o + td. بعد ذلك، مشكلة   تقرير ما إذا كان p هو داخل   يتم تخفيض المضلع من ثلاثة إلى اثنين   أبعاد ...

وانظر كتاب لمزيد من التفاصيل.

نصائح أخرى

struct point
{
    float x
    float y
    float z
}

struct ray
{
    point R1
    point R2
}

struct polygon
{
    point P[]
    int count
}

float dotProduct(point A, point B)
{
    return A.x*B.x + A.y*B.y + A.z*B.z
}

point crossProduct(point A, point B)
{
    return point(A.y*B.z-A.z*B.y, A.z*B.x-A.x*B.z, A.x*B.y-A.y*B.x)
}

point vectorSub(point A, point B)
{
    return point(A.x-B.x, A.y-B.y, A.z-B.z) 
}

point scalarMult(float a, Point B)
{
    return point(a*B.x, a*B.y, a*B.z)
}

bool findIntersection(ray Ray, polygon Poly, point& Answer)
{
    point plane_normal = crossProduct(vectorSub(Poly.P[1], Poly.P[0]), vectorSub(Poly.P[2], Poly.P[0]))

    float denominator = dotProduct(vectorSub(Ray.R2, Poly.P[0]), plane_normal)

    if (denominator == 0) { return FALSE } // ray is parallel to the polygon

    float ray_scalar = dotProduct(vectorSub(Poly.P[0], Ray.R1), plane_normal)

    Answer = vectorAdd(Ray.R1, scalarMult(ray_scalar, Ray.R2))

    // verify that the point falls inside the polygon

    point test_line = vectorSub(Answer, Poly.P[0])
    point test_axis = crossProduct(plane_normal, test_line)

    bool point_is_inside = FALSE

    point test_point = vectorSub(Poly.P[1], Answer)
    bool prev_point_ahead = (dotProduct(test_line, test_point) > 0)
    bool prev_point_above = (dotProduct(test_axis, test_point) > 0)

    bool this_point_ahead
    bool this_point_above

    int index = 2;
    while (index < Poly.count)
    {
        test_point = vectorSub(Poly.P[index], Answer)
        this_point_ahead = (dotProduct(test_line, test_point) > 0)

        if (prev_point_ahead OR this_point_ahead)
        {
            this_point_above = (dotProduct(test_axis, test_point) > 0)

            if (prev_point_above XOR this_point_above)
            {
                point_is_inside = !point_is_inside
            }
        }

        prev_point_ahead = this_point_ahead
        prev_point_above = this_point_above
        index++
    }

    return point_is_inside
}

لقد تم تخصيص فصول كاملة من الكتاب لهذا المطلب بالتحديد - ومن الطويل جدًا وصف الخوارزمية المناسبة هنا.أقترح قراءة أي عدد من الأعمال المرجعية في مجال الرسومات الحاسوبية، على وجه الخصوص:

  • مقدمة لتتبع الأشعة، أد.أندرو س.غلاسنر، ISBN 0122861604
function Collision(PlaneOrigin,PlaneDirection,RayOrigin,RayDirection)
    return RayOrigin-RayDirection*Dot(PlaneDirection,RayOrigin-PlaneOrigin)/Dot(PlaneDirection,RayDirection)
end

و(PlaneDirection هو متجه الوحدة الذي هو عمودي على الطائرة)

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