⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mgcintrlin3sphr.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement.  The various license agreements may be found at
// the Magic Software web site.  This file is subject to the license
//
// FREE SOURCE CODE
// http://www.magic-software.com/License/free.pdf

#include "MgcDistVec3Lin3.h"
#include "MgcIntrLin3Sphr.h"

//----------------------------------------------------------------------------
bool MgcTestIntersection (const MgcSegment3& rkSegment,
    const MgcSphere& rkSphere)
{
    MgcReal fSqrDist = MgcSqrDistance(rkSphere.Center(),rkSegment);
    return fSqrDist <= rkSphere.Radius();
}
//----------------------------------------------------------------------------
bool MgcTestIntersection (const MgcRay3& rkRay, const MgcSphere& rkSphere)
{
    MgcReal fSqrDist = MgcSqrDistance(rkSphere.Center(),rkRay);
    return fSqrDist <= rkSphere.Radius();
}
//----------------------------------------------------------------------------
bool MgcTestIntersection (const MgcLine3& rkLine, const MgcSphere& rkSphere)
{
    MgcReal fSqrDist = MgcSqrDistance(rkSphere.Center(),rkLine);
    return fSqrDist <= rkSphere.Radius();
}
//----------------------------------------------------------------------------
bool MgcFindIntersection (const MgcSegment3& rkSegment,
    const MgcSphere& rkSphere, int& riQuantity, MgcVector3 akPoint[2])
{
    // set up quadratic Q(t) = a*t^2 + 2*b*t + c
    MgcVector3 kDiff = rkSegment.Origin() - rkSphere.Center();
    MgcReal fA = rkSegment.Direction().SquaredLength();
    MgcReal fB = kDiff.Dot(rkSegment.Direction());
    MgcReal fC = kDiff.SquaredLength() -
        rkSphere.Radius()*rkSphere.Radius();

    // no intersection if Q(t) has no real roots
    MgcReal afT[2];
    MgcReal fDiscr = fB*fB - fA*fC;
    if ( fDiscr < 0.0 )
    {
        riQuantity = 0;
    }
    else if ( fDiscr > 0.0 )
    {
        MgcReal fRoot = MgcMath::Sqrt(fDiscr);
        MgcReal fInvA = 1.0/fA;
        afT[0] = (-fB - fRoot)*fInvA;
        afT[1] = (-fB + fRoot)*fInvA;

        if ( afT[0] > 1.0 )
            riQuantity = 0;
        else if ( afT[0] >= 0.0 )
            riQuantity = ( afT[1] > 1.0 ? 1 : 2 );
        else if ( afT[1] >= 0.0 )
            riQuantity = 1;
        else
            riQuantity = 0;
    }
    else
    {
        afT[0] = -fB/fA;
        riQuantity = ( 0.0 <= afT[0] && afT[0] <= 1.0 ? 1 : 0 );
    }

    for (int i = 0; i < riQuantity; i++)
        akPoint[i] = rkSegment.Origin() + afT[i]*rkSegment.Direction();

    return riQuantity > 0;
}
//----------------------------------------------------------------------------
bool MgcFindIntersection (const MgcRay3& rkRay, const MgcSphere& rkSphere,
    int& riQuantity, MgcVector3 akPoint[2])
{
    // set up quadratic Q(t) = a*t^2 + 2*b*t + c
    MgcVector3 kDiff = rkRay.Origin() - rkSphere.Center();
    MgcReal fA = rkRay.Direction().SquaredLength();
    MgcReal fB = kDiff.Dot(rkRay.Direction());
    MgcReal fC = kDiff.SquaredLength() -
        rkSphere.Radius()*rkSphere.Radius();

    MgcReal afT[2];
    MgcReal fDiscr = fB*fB - fA*fC;
    if ( fDiscr < 0.0 )
    {
        riQuantity = 0;
    }
    else if ( fDiscr > 0.0 )
    {
        MgcReal fRoot = MgcMath::Sqrt(fDiscr);
        MgcReal fInvA = 1.0/fA;
        afT[0] = (-fB - fRoot)*fInvA;
        afT[1] = (-fB + fRoot)*fInvA;

        if ( afT[0] >= 0.0 )
            riQuantity = 2;
        else if ( afT[1] >= 0.0 )
            riQuantity = 1;
        else
            riQuantity = 0;
    }
    else
    {
        afT[0] = -fB/fA;
        riQuantity = ( afT[0] >= 0.0 ? 1 : 0 );
    }

    for (int i = 0; i < riQuantity; i++)
        akPoint[i] = rkRay.Origin() + afT[i]*rkRay.Direction();

    return riQuantity > 0;
}
//----------------------------------------------------------------------------
bool MgcFindIntersection (const MgcLine3& rkLine,
    const MgcSphere& rkSphere, int& riQuantity, MgcVector3 akPoint[2])
{
    // set up quadratic Q(t) = a*t^2 + 2*b*t + c
    MgcVector3 kDiff = rkLine.Origin() - rkSphere.Center();
    MgcReal fA = rkLine.Direction().SquaredLength();
    MgcReal fB = kDiff.Dot(rkLine.Direction());
    MgcReal fC = kDiff.SquaredLength() -
        rkSphere.Radius()*rkSphere.Radius();

    MgcReal afT[2];
    MgcReal fDiscr = fB*fB - fA*fC;
    if ( fDiscr < 0.0 )
    {
        riQuantity = 0;
    }
    else if ( fDiscr > 0.0 )
    {
        MgcReal fRoot = MgcMath::Sqrt(fDiscr);
        MgcReal fInvA = 1.0/fA;
        riQuantity = 2;
        afT[0] = (-fB - fRoot)*fInvA;
        afT[1] = (-fB + fRoot)*fInvA;
    }
    else
    {
        riQuantity = 1;
        afT[0] = -fB/fA;
    }

    for (int i = 0; i < riQuantity; i++)
        akPoint[i] = rkLine.Origin() + afT[i]*rkLine.Direction();

    return riQuantity > 0;
}
//----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -