📄 mgcbeziercylinder2g.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 "MgcBezierCylinder2G.h"
//----------------------------------------------------------------------------
MgcBezierCylinder2G::MgcBezierCylinder2G (MgcVector3* akCtrlPoint)
:
MgcBezierCylinderG(2,akCtrlPoint)
{
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierCylinder2G::GetPosition (MgcReal fU, MgcReal fV) const
{
MgcReal fOmU = 1.0 - fU;
MgcReal afUCoeff[3] =
{
fOmU*fOmU,
2.0*fOmU*fU,
fU*fU
};
MgcReal fOmV = 1.0 - fV;
MgcVector3 kB0 = MgcVector3::ZERO, kB1 = MgcVector3::ZERO;
for (int iX = 0; iX < 3; iX++)
{
kB0 += afUCoeff[iX]*m_akCtrlPoint[iX];
kB1 += afUCoeff[iX]*m_akCtrlPoint[iX + 3];
}
MgcVector3 kResult = fOmV*kB0 + fV*kB1;
return kResult;
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierCylinder2G::GetDerivativeU (MgcReal fU, MgcReal fV) const
{
MgcReal fOmU = 1.0 - fU;
MgcReal afUCoeff[3] =
{
-2.0*fOmU,
2.0*(fOmU - fU),
2.0*fU
};
MgcReal fOmV = 1.0 - fV;
MgcVector3 kB0 = MgcVector3::ZERO, kB1 = MgcVector3::ZERO;
for (int iX = 0; iX < 3; iX++)
{
kB0 += afUCoeff[iX]*m_akCtrlPoint[iX];
kB1 += afUCoeff[iX]*m_akCtrlPoint[iX + 3];
}
MgcVector3 kResult = fOmV*kB0 + fV*kB1;
return kResult;
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierCylinder2G::GetDerivativeV (MgcReal fU, MgcReal fV) const
{
MgcReal fOmU = 1.0 - fU;
MgcReal afUCoeff[3] =
{
fOmU*fOmU,
2.0*fOmU*fU,
fU*fU
};
MgcVector3 kB0 = MgcVector3::ZERO, kB1 = MgcVector3::ZERO;
for (int iX = 0; iX < 3; iX++)
{
kB0 += afUCoeff[iX]*m_akCtrlPoint[iX];
kB1 += afUCoeff[iX]*m_akCtrlPoint[iX + 3];
}
MgcVector3 kResult = kB1 - kB0;
return kResult;
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierCylinder2G::GetDerivativeUU (MgcReal fU, MgcReal fV) const
{
MgcReal afUCoeff[3] =
{
2.0,
-4.0,
2.0
};
MgcReal fOmV = 1.0 - fV;
MgcVector3 kB0 = MgcVector3::ZERO, kB1 = MgcVector3::ZERO;
for (int iX = 0; iX < 3; iX++)
{
kB0 += afUCoeff[iX]*m_akCtrlPoint[iX];
kB1 += afUCoeff[iX]*m_akCtrlPoint[iX + 3];
}
MgcVector3 kResult = fOmV*kB0 + fV*kB1;
return kResult;
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierCylinder2G::GetDerivativeUV (MgcReal fU, MgcReal fV) const
{
MgcReal fOmU = 1.0 - fU;
MgcReal afUCoeff[3] =
{
-2.0*fOmU,
2.0*(fOmU - fU),
2.0*fU
};
MgcVector3 kB0 = MgcVector3::ZERO, kB1 = MgcVector3::ZERO;
for (int iX = 0; iX < 3; iX++)
{
kB0 += afUCoeff[iX]*m_akCtrlPoint[iX];
kB1 += afUCoeff[iX]*m_akCtrlPoint[iX + 3];
}
MgcVector3 kResult = kB1 - kB0;
return kResult;
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierCylinder2G::GetDerivativeVV (MgcReal fU, MgcReal fV) const
{
return MgcVector3::ZERO;
}
//----------------------------------------------------------------------------
void MgcBezierCylinder2G::Tessellate (unsigned int uiLevel, bool bWantNormals)
{
// allocate arrays and compute connectivity
Initialize(uiLevel,bWantNormals);
// indices of four corners of patch, I[u][v]
unsigned int uiTwoPowL = (1 << uiLevel);
unsigned int uiTwoPowC = (1 << m_uiCylinderLevel);
IntervalParameters kIP;
kIP.m_uiI00 = 0;
kIP.m_uiI01 = uiTwoPowC*(uiTwoPowL + 1);
kIP.m_uiI10 = uiTwoPowL;
kIP.m_uiI11 = kIP.m_uiI01 + uiTwoPowL;
// vertices for subdivision
MgcVector3* akX = m_akVertex;
akX[kIP.m_uiI00] = m_akCtrlPoint[0];
akX[kIP.m_uiI01] = m_akCtrlPoint[3];
akX[kIP.m_uiI10] = m_akCtrlPoint[2];
akX[kIP.m_uiI11] = m_akCtrlPoint[5];
// derivatives for subdivision (for normal vectors)
MgcVector3* akXu;
MgcVector3* akXv;
if ( bWantNormals )
{
akXu = new MgcVector3[m_uiVertexQuantity];
akXu[kIP.m_uiI00] = 2.0*(m_akCtrlPoint[1] - m_akCtrlPoint[0]);
akXu[kIP.m_uiI01] = 2.0*(m_akCtrlPoint[4] - m_akCtrlPoint[3]);
akXu[kIP.m_uiI10] = 2.0*(m_akCtrlPoint[2] - m_akCtrlPoint[1]);
akXu[kIP.m_uiI11] = 2.0*(m_akCtrlPoint[5] - m_akCtrlPoint[4]);
akXv = new MgcVector3[m_uiVertexQuantity];
akXv[kIP.m_uiI00] = 2.0*(m_akCtrlPoint[3] - m_akCtrlPoint[0]);
akXv[kIP.m_uiI01] = akXv[kIP.m_uiI00];
akXv[kIP.m_uiI10] = 2.0*(m_akCtrlPoint[5] - m_akCtrlPoint[2]);
akXv[kIP.m_uiI11] = akXv[kIP.m_uiI10];
}
else
{
akXu = 0;
akXv = 0;
}
// recursive subdivision
if ( uiLevel > 0 || m_uiCylinderLevel > 0 )
{
kIP.m_aakXuu[0] = 6.0*(m_akCtrlPoint[0] - 2.0*m_akCtrlPoint[1] +
m_akCtrlPoint[2]);
kIP.m_aakXuu[1] = 6.0*(m_akCtrlPoint[3] - 2.0*m_akCtrlPoint[4] +
m_akCtrlPoint[5]);
}
if ( uiLevel > 0 )
SubdivideBoundary(--uiLevel,0.25,akX,akXu,akXv,kIP);
if ( m_uiCylinderLevel > 0 )
{
SubdivideCylinder(m_uiCylinderLevel-1,akX,akXu,akXv,0,kIP.m_uiI01,
uiTwoPowL);
}
// calculate unit-length normals from derivative vectors
if ( bWantNormals )
{
for (unsigned int uiI = 0; uiI < m_uiVertexQuantity; uiI++)
m_akNormal[uiI] = akXu[uiI].UnitCross(akXv[uiI]);
delete[] akXu;
delete[] akXv;
}
}
//----------------------------------------------------------------------------
void MgcBezierCylinder2G::SubdivideBoundary (unsigned int uiLevel,
MgcReal fDSqr, MgcVector3* akX, MgcVector3* akXu, MgcVector3* akXv,
IntervalParameters& rkIP)
{
// subdivision indices
unsigned int uiIM0 = (rkIP.m_uiI00 + rkIP.m_uiI10) >> 1;
unsigned int uiIM1 = (rkIP.m_uiI01 + rkIP.m_uiI11) >> 1;
// vertices
akX[uiIM0] = 0.5*(akX[rkIP.m_uiI00] + akX[rkIP.m_uiI10] -
fDSqr*rkIP.m_aakXuu[0]);
akX[uiIM1] = 0.5*(akX[rkIP.m_uiI01] + akX[rkIP.m_uiI11] -
fDSqr*rkIP.m_aakXuu[1]);
// derivatives (for normal vectors)
if ( akXu )
{
akXu[uiIM0] = 0.5*(akXu[rkIP.m_uiI00] + akXu[rkIP.m_uiI10]);
akXu[uiIM1] = 0.5*(akXu[rkIP.m_uiI01] + akXu[rkIP.m_uiI11]);
akXv[uiIM0] = akX[uiIM1] - akX[uiIM0];
akXv[uiIM1] = akXv[uiIM0];
}
// recurse on two children
if ( uiLevel > 0 )
{
uiLevel--;
fDSqr *= 0.25;
IntervalParameters kSubIP;
// subinterval [s0,sM]
kSubIP.m_uiI00 = rkIP.m_uiI00;
kSubIP.m_uiI01 = rkIP.m_uiI01;
kSubIP.m_uiI10 = uiIM0;
kSubIP.m_uiI11 = uiIM1;
kSubIP.m_aakXuu[0] = rkIP.m_aakXuu[0];
kSubIP.m_aakXuu[1] = rkIP.m_aakXuu[1];
SubdivideBoundary(uiLevel,fDSqr,akX,akXu,akXv,kSubIP);
// subinterval [sM,s1]
kSubIP.m_uiI00 = uiIM0;
kSubIP.m_uiI01 = uiIM1;
kSubIP.m_uiI10 = rkIP.m_uiI10;
kSubIP.m_uiI11 = rkIP.m_uiI11;
kSubIP.m_aakXuu[0] = rkIP.m_aakXuu[0];
kSubIP.m_aakXuu[1] = rkIP.m_aakXuu[1];
SubdivideBoundary(uiLevel,fDSqr,akX,akXu,akXv,kSubIP);
}
}
//----------------------------------------------------------------------------
void MgcBezierCylinder2G::SubdivideCylinder (unsigned int uiCLevel,
MgcVector3* akX, MgcVector3* akXu, MgcVector3* akXv, unsigned int uiI0,
unsigned int uiI1, unsigned int uiTwoPowL)
{
// subdivision index
unsigned int uiIM = (uiI0 + uiI1) >> 1;
unsigned int uiJ0 = uiI0, uiJM = uiIM, uiJ1 = uiI1;
unsigned int uiJLast = uiJM + uiTwoPowL;
for (/**/; uiJM <= uiJLast; uiJ0++, uiJM++, uiJ1++)
{
// vertices
akX[uiJM] = 0.5*(akX[uiJ0] + akX[uiJ1]);
// derivatives (for normal vectors)
if ( akXu )
{
akXu[uiJM] = 0.5*(akXu[uiJ0] + akXu[uiJ1]);
akXv[uiJM] = akXv[uiJ0];
}
}
// recurse on two children
if ( uiCLevel > 0 )
{
uiCLevel--;
// subinterval [t0,tM]
SubdivideCylinder(uiCLevel,akX,akXu,akXv,uiI0,uiIM,uiTwoPowL);
// subinterval [tM,t1]
SubdivideCylinder(uiCLevel,akX,akXu,akXv,uiIM,uiI1,uiTwoPowL);
}
}
//----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -