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

📄 mgccontsphere.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 "MgcContSphere.h"

//----------------------------------------------------------------------------
MgcSphere MgcContSphereOfAABB (int iQuantity, const MgcVector3* akPoint)
{
    MgcVector3 kMin = akPoint[0], kMax = kMin;
    for (int i = 1; i < iQuantity; i++)
    {
        if ( akPoint[i].x < kMin.x )
            kMin.x = akPoint[i].x;
        else if ( akPoint[i].x > kMax.x )
            kMax.x = akPoint[i].x;

        if ( akPoint[i].y < kMin.y )
            kMin.y = akPoint[i].y;
        else if ( akPoint[i].y > kMax.y )
            kMax.y = akPoint[i].y;

        if ( akPoint[i].z < kMin.z )
            kMin.z = akPoint[i].z;
        else if ( akPoint[i].z > kMax.z )
            kMax.z = akPoint[i].z;
    }

    MgcSphere kSphere;
    kSphere.Center() = 0.5*(kMax + kMin);
    MgcVector3 kHalfDiagonal = 0.5*(kMax - kMin);
    kSphere.Radius() = kHalfDiagonal.Length();

    return kSphere;
}
//----------------------------------------------------------------------------
MgcSphere MgcContSphereAverage (int iQuantity, const MgcVector3* akPoint)
{
    MgcVector3 kCenter = akPoint[0];
    int i;
    for (i = 1; i < iQuantity; i++)
        kCenter += akPoint[i];
    MgcReal fInvQuantity = 1.0/iQuantity;
    kCenter *= fInvQuantity;

    MgcReal fMaxRadiusSqr = 0.0;
    for (i = 0; i < iQuantity; i++)
    {
        MgcVector3 kDiff = akPoint[i] - kCenter;
        MgcReal fRadiusSqr = kDiff.SquaredLength();
        if ( fRadiusSqr > fMaxRadiusSqr )
            fMaxRadiusSqr = fRadiusSqr;
    }

    MgcSphere kSphere;
    kSphere.Center() = kCenter;
    kSphere.Radius() = MgcMath::Sqrt(fMaxRadiusSqr);

    return kSphere;
}
//----------------------------------------------------------------------------
bool MgcContSphereOfAABB (int iQuantity, const MgcVector3* akPoint,
    const bool* abValid, MgcSphere& rkSphere)
{
    MgcVector3 kMin, kMax;
    int i;
    for (i = 0; i < iQuantity; i++)
    {
        if ( abValid[i] )
        {
            kMin = akPoint[i];
            kMax = kMin;
            break;
        }
    }
    if ( i == iQuantity )
        return false;

    for (i++; i < iQuantity; i++)
    {
        if ( abValid[i] )
        {
            if ( akPoint[i].x < kMin.x )
                kMin.x = akPoint[i].x;
            else if ( akPoint[i].x > kMax.x )
                kMax.x = akPoint[i].x;

            if ( akPoint[i].y < kMin.y )
                kMin.y = akPoint[i].y;
            else if ( akPoint[i].y > kMax.y )
                kMax.y = akPoint[i].y;

            if ( akPoint[i].z < kMin.z )
                kMin.z = akPoint[i].z;
            else if ( akPoint[i].z > kMax.z )
                kMax.z = akPoint[i].z;
        }
    }

    rkSphere.Center() = 0.5*(kMax + kMin);
    MgcVector3 kHalfDiagonal = 0.5*(kMax - kMin);
    rkSphere.Radius() = kHalfDiagonal.Length();

    return true;
}
//----------------------------------------------------------------------------
bool MgcContSphereAverage (int iQuantity, const MgcVector3* akPoint,
    const bool* abValid, MgcSphere& rkSphere)
{
    MgcVector3 kCenter = MgcVector3::ZERO;
    int i, iValidQuantity = 0;
    for (i = 0; i < iQuantity; i++)
    {
        if ( abValid[i] )
        {
            kCenter += akPoint[i];
            iValidQuantity++;
        }
    }
    if ( iValidQuantity == 0 )
        return false;

    MgcReal fInvQuantity = 1.0/iValidQuantity;
    kCenter *= fInvQuantity;

    MgcReal fMaxRadiusSqr = 0.0;
    for (i = 0; i < iQuantity; i++)
    {
        if ( abValid[i] )
        {
            MgcVector3 kDiff = akPoint[i] - kCenter;
            MgcReal fRadiusSqr = kDiff.SquaredLength();
            if ( fRadiusSqr > fMaxRadiusSqr )
                fMaxRadiusSqr = fRadiusSqr;
        }
    }

    rkSphere.Center() = kCenter;
    rkSphere.Radius() = MgcMath::Sqrt(fMaxRadiusSqr);

    return true;
}
//----------------------------------------------------------------------------
MgcSphere MgcMergeSpheres (const MgcSphere& rkSphere0,
    const MgcSphere& rkSphere1)
{
    MgcVector3 kCDiff = rkSphere1.Center() - rkSphere0.Center();
    MgcReal fLSqr = kCDiff.SquaredLength();
    MgcReal fRDiff = rkSphere1.Radius() - rkSphere0.Radius();
    MgcReal fRDiffSqr = fRDiff*fRDiff;

    if ( fRDiffSqr >= fLSqr )
        return ( fRDiff >= 0.0 ? rkSphere1 : rkSphere0 );

    MgcReal fLength = MgcMath::Sqrt(fLSqr);
    const MgcReal fTolerance = 1e-06;
    MgcSphere kSphere;

    if ( fLength > fTolerance )
    {
        MgcReal fCoeff = (fLength + fRDiff)/(2.0*fLength);
        kSphere.Center() = rkSphere0.Center() + fCoeff*kCDiff;
    }
    else
    {
        kSphere.Center() = rkSphere0.Center();
    }

    kSphere.Radius() = 0.5*(fLength + rkSphere0.Radius() +
        rkSphere1.Radius());

    return kSphere;
}
//----------------------------------------------------------------------------

⌨️ 快捷键说明

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