📄 mgcbeziertriangle2g.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 "MgcBezierTriangle2G.h"
//----------------------------------------------------------------------------
MgcBezierTriangle2G::MgcBezierTriangle2G (MgcVector3* akCtrlPoint)
:
MgcBezierTriangleG(2,akCtrlPoint)
{
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierTriangle2G::GetPosition (MgcReal fU, MgcReal fV) const
{
MgcReal fW = 1.0 - fU - fV;
MgcReal fU2 = fU*fU, fV2 = fV*fV, fW2 = fW*fW;
MgcReal f2UV = 2.0*fU*fV, f2UW = 2.0*fU*fW, f2VW = 2.0*fV*fW;
return fW2*m_akCtrlPoint[0] + f2UW*m_akCtrlPoint[1] +
fU2*m_akCtrlPoint[2] + f2VW*m_akCtrlPoint[3] + f2UV*m_akCtrlPoint[4] +
fV2*m_akCtrlPoint[5];
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierTriangle2G::GetDerivativeU (MgcReal fU, MgcReal fV) const
{
MgcReal fW = 1.0 - fU - fV;
return 2.0*(-fW*m_akCtrlPoint[0] + (fW-fU)*m_akCtrlPoint[1] +
fU*m_akCtrlPoint[2] - fV*m_akCtrlPoint[3] + fV*m_akCtrlPoint[4]);
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierTriangle2G::GetDerivativeV (MgcReal fU, MgcReal fV) const
{
MgcReal fW = 1.0 - fU - fV;
return 2.0*(-fW*m_akCtrlPoint[0] - fU*m_akCtrlPoint[1] +
(fW-fU)*m_akCtrlPoint[3] + fU*m_akCtrlPoint[4] +
fV*m_akCtrlPoint[5]);
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierTriangle2G::GetDerivativeUU (MgcReal fU, MgcReal fV) const
{
return 2.0*(m_akCtrlPoint[0] - 2.0*m_akCtrlPoint[1] + m_akCtrlPoint[2]);
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierTriangle2G::GetDerivativeUV (MgcReal fU, MgcReal fV) const
{
return 2.0*(m_akCtrlPoint[0] - m_akCtrlPoint[1] - m_akCtrlPoint[3] +
m_akCtrlPoint[4]);
}
//----------------------------------------------------------------------------
MgcVector3 MgcBezierTriangle2G::GetDerivativeVV (MgcReal fU, MgcReal fV) const
{
return 2.0*(m_akCtrlPoint[0] - 2.0*m_akCtrlPoint[3] + m_akCtrlPoint[5]);
}
//----------------------------------------------------------------------------
void MgcBezierTriangle2G::Tessellate (unsigned int uiLevel, bool bWantNormals)
{
// allocate arrays and compute connectivity
Initialize(uiLevel,bWantNormals);
// indices of three corners of patch, I0 (w=1), I1 (u=1), I2 (v=1)
unsigned int uiTwoPowL = (1 << uiLevel);
unsigned int uiI0 = 0;
unsigned int uiI1 = uiTwoPowL;
unsigned int uiI2 = uiTwoPowL*(uiTwoPowL + 3) >> 1;
// vertices for subdivision
MgcVector3* akX = m_akVertex;
akX[uiI0] = m_akCtrlPoint[0];
akX[uiI1] = m_akCtrlPoint[2];
akX[uiI2] = m_akCtrlPoint[5];
// derivatives for subdivision (for normal vectors)
MgcVector3* akXu;
MgcVector3* akXv;
if ( bWantNormals )
{
akXu = new MgcVector3[m_uiVertexQuantity];
akXu[uiI0] = 2.0*(m_akCtrlPoint[1] - m_akCtrlPoint[0]);
akXu[uiI1] = 2.0*(m_akCtrlPoint[2] - m_akCtrlPoint[1]);
akXu[uiI2] = 2.0*(m_akCtrlPoint[4] - m_akCtrlPoint[3]);
akXv = new MgcVector3[m_uiVertexQuantity];
akXv[uiI0] = 2.0*(m_akCtrlPoint[3] - m_akCtrlPoint[0]);
akXv[uiI1] = 2.0*(m_akCtrlPoint[5] - m_akCtrlPoint[3]);
akXv[uiI2] = 2.0*(m_akCtrlPoint[4] - m_akCtrlPoint[1]);
}
else
{
akXu = 0;
akXv = 0;
}
// recursive subdivision
if ( uiLevel > 0 )
{
BlockParameters kBP;
kBP.m_kXuu = 2.0*(m_akCtrlPoint[0] - 2.0*m_akCtrlPoint[1] +
m_akCtrlPoint[2]);
kBP.m_kXvv = 2.0*(m_akCtrlPoint[0] - 2.0*m_akCtrlPoint[3] +
m_akCtrlPoint[5]);
kBP.m_kXhh = 2.0*(m_akCtrlPoint[0] + m_akCtrlPoint[4] -
m_akCtrlPoint[1] - m_akCtrlPoint[3]);
SubdivideLL(--uiLevel,0.25,akX,akXu,akXv,uiI0,uiI1,uiI2,kBP);
}
// 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 MgcBezierTriangle2G::SubdivideLL (unsigned int uiLevel, MgcReal fDSqr,
MgcVector3* akX, MgcVector3* akXu, MgcVector3* akXv, unsigned int uiI0,
unsigned int uiI1, unsigned int uiI2, BlockParameters& rkBP)
{
/*
i2
+
| \
| \
+----+
i0 i1
*/
// subdivision indices
unsigned int uiI01 = (uiI0 + uiI1) >> 1;
unsigned int uiD10 = uiI1 - uiI0;
unsigned int uiI02 = (((uiI0 + uiI2) << 2) + uiD10*uiD10) >> 3;
unsigned int uiI12 = uiI02 + (uiD10 >> 1);
// vertices
// bottom u-edge subdivision
akX[uiI01] = 0.5*(akX[uiI0] + akX[uiI1] - fDSqr*rkBP.m_kXuu);
// left v-edge subdivision
akX[uiI02] = 0.5*(akX[uiI0] + akX[uiI2] - fDSqr*rkBP.m_kXvv);
// hypotenuse edge subdivision
akX[uiI12] = 0.5*(akX[uiI1] + akX[uiI2] - fDSqr*rkBP.m_kXhh);
// derivatives (for normal vectors)
if ( akXu )
{
// bottom u-edge subdivision
akXu[uiI01] = 0.5*(akXu[uiI0] + akXu[uiI1]);
akXv[uiI01] = 0.5*(akXv[uiI0] + akXv[uiI1]);
// left v-edge subdivision
akXu[uiI02] = 0.5*(akXu[uiI0] + akXu[uiI2]);
akXv[uiI02] = 0.5*(akXv[uiI0] + akXv[uiI2]);
// hypotenuse edge subdivision
akXu[uiI12] = 0.5*(akXu[uiI1] + akXu[uiI2]);
akXv[uiI12] = 0.5*(akXv[uiI1] + akXv[uiI2]);
}
// recurse on four children
if ( uiLevel > 0 )
{
uiLevel--;
fDSqr *= 0.25;
// subtriangle <(s0,t0),(sm,t0),(s0,tm)>
SubdivideLL(uiLevel,fDSqr,akX,akXu,akXv,uiI0,uiI01,uiI02,rkBP);
// subtriangle <(sm,t0),(s1,t0),(sm,tm)>
SubdivideLL(uiLevel,fDSqr,akX,akXu,akXv,uiI01,uiI1,uiI12,rkBP);
// subtriangle <(s0,tm),(sm,tm),(s0,t1)>
SubdivideLL(uiLevel,fDSqr,akX,akXu,akXv,uiI02,uiI12,uiI2,rkBP);
// subtriangle <(sm,t0),(sm,tm),(s0,tm)>
SubdivideUR(uiLevel,fDSqr,akX,akXu,akXv,uiI01,uiI12,uiI02,rkBP);
}
}
//----------------------------------------------------------------------------
void MgcBezierTriangle2G::SubdivideUR (unsigned int uiLevel, MgcReal fDSqr,
MgcVector3* akX, MgcVector3* akXu, MgcVector3* akXv, unsigned int uiI0,
unsigned int uiI1, unsigned int uiI2, BlockParameters& rkBP)
{
/*
i2 i1
+----+
\ |
\|
+
i0
*/
// subdivision indices
unsigned int uiI12 = (uiI1 + uiI2) >> 1;
unsigned int uiD12 = uiI1 - uiI2;
unsigned int uiI01 = (((uiI0 + uiI1) << 2) + uiD12*uiD12) >> 3;
unsigned int uiI02 = uiI01 - (uiD12 >> 1);
// vertices
// top u-edge subdivision
akX[uiI12] = 0.5*(akX[uiI1] + akX[uiI2] - fDSqr*rkBP.m_kXuu);
// right v-edge subdivision
akX[uiI01] = 0.5*(akX[uiI0] + akX[uiI1] - fDSqr*rkBP.m_kXvv);
// hypotenuse edge subdivision
akX[uiI02] = 0.5*(akX[uiI0] + akX[uiI2] - fDSqr*rkBP.m_kXhh);
// recurse on four children
if ( uiLevel > 0 )
{
uiLevel--;
fDSqr *= 0.25;
// subtriangle <(sm,tm),(sm,t1),(s0,t1)>
SubdivideUR(uiLevel,fDSqr,akX,akXu,akXv,uiI02,uiI12,uiI2,rkBP);
// subtriangle <(s1,tm),(s1,t1),(sm,t1)>
SubdivideUR(uiLevel,fDSqr,akX,akXu,akXv,uiI01,uiI1,uiI12,rkBP);
// subtriangle <(s1,t0),(s1,tm),(sm,tm)>
SubdivideUR(uiLevel,fDSqr,akX,akXu,akXv,uiI0,uiI01,uiI02,rkBP);
// subtriangle <(sm,tm),(s1,tm),(sm,t1)>
SubdivideLL(uiLevel,fDSqr,akX,akXu,akXv,uiI02,uiI01,uiI12,rkBP);
}
}
//----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -