部分位置函数无关紧要。
//获取视点
CATFrmLayout *pLaout=CATFrmLayout::GetCurrentLayout();
CATFrmWindow *pFrmWindow=pLaout->GetCurrentWindow();
CATViewer *pViewer=pFrmWindow->GetViewer();
CAT3DViewpoint *pViewpoint=&(pViewer->GetMain3DViewpoint());
Point ViewPoint;
Direction SightDir;
CATMathPointf Originf=pViewpoint->GetOrigin();
Originf.GetValue(ViewPoint);
CATMathDirectionf SightDirf=pViewpoint->GetSightDirection();
SightDirf.GetValue(SightDir);
Point OrignalPoint = _pproduct -> GetRootBox() -> GetCenter();
Transfor absPosition;
_pproduct -> GetAbsPosition(absPosition);
OrignalPoint=absPosition*OrignalPoint;
Vector ViewToGrav=OrignalPoint-ViewPoint;
double dist=abs(ViewToGrav*SightDir);
// Length of the cylinder
float length=(float)0.125*dist;
// Radius of the faces
float radius=(float)0.006*dist;
// Variables used for face creation
int nbTriangles = 0;
int nbStrips = 0;
int nbFans = 0;
int * nbStripVertices = NULL;
int * nbFanVertices = NULL;
int * triangleIndices = NULL;
int * stripIndices = NULL;
int * fanIndices = NULL;
float normal[3] = { 0.0f, 0.0f, 0.0f };
Transfor DirTrans=this -> GetDirPosition();
if (_PosRadioButton->GetState()==CATDlgUncheck)
{
Transfor NegTrans(Matrix(
Vector(1.,.0,.0),Vector(.0,-1.,.0),Vector(.0,.0,-1.)),Vector());
DirTrans=DirTrans*NegTrans;
}
// Number of points wanted in order to tesselate the top and bottom faces
unsigned int nbFaceVertices = 40;
// Create the needed arrays for storing faces vertices
float * topVertices = new float[nbFaceVertices*3];
float * bottomVertices = new float[nbFaceVertices*3];
// The body face will need all the vertices from both the top and
// bottom faces
float * bodyVertices = new float[2*nbFaceVertices*3];
float * bodyNormals = new float[2*nbFaceVertices*3];
float bodyLineVertices[12];
// Compute the vertices of the faces
double angle = 0;
double increment = CAT2PI/nbFaceVertices;
Point topVerticesP(.0,.0,.0);
Point bottomVerticesP(.0,.0,.0);
for(unsigned int i=0;i<nbFaceVertices;++i)
{
// Compute position
float x = radius*(float)cos(angle);
float y = radius*(float)sin(angle);
float zTop = length;
float zBottom = .0f;
topVerticesP.SetX(x);
topVerticesP.SetY(y);
topVerticesP.SetZ(zTop);
topVerticesP=DirTrans*topVerticesP;
bottomVerticesP.SetX(x);
bottomVerticesP.SetY(y);
bottomVerticesP.SetZ(zBottom);
bottomVerticesP=DirTrans*bottomVerticesP;
float xTopP=(float)topVerticesP.GetX();
float yTopP=(float)topVerticesP.GetY();
float zTopP=(float)topVerticesP.GetZ();
float xBottomP=(float)bottomVerticesP.GetX();
float yBottomP=(float)bottomVerticesP.GetY();
float zBottomP=(float)bottomVerticesP.GetZ();
// Fill in top face vertices
topVertices[3*i] = xTopP;
topVertices[3*i+1] = yTopP;
topVertices[3*i+2] = zTopP;
// Fill in bottom face vertices
bottomVertices[3*i] = xBottomP;
bottomVertices[3*i+1] = yBottomP;
bottomVertices[3*i+2] = zBottomP;
// Fill in body face vertices.
// Body vertices array interleaves the points of the top and bottom face
bodyVertices[6*i] = xTopP;
bodyVertices[6*i+1] = yTopP;
bodyVertices[6*i+2] = zTopP;
bodyVertices[6*i+3] = xBottomP;
bodyVertices[6*i+4] = yBottomP;
bodyVertices[6*i+5] = zBottomP;
// Fill in body line vertices
if(i == 0)
{
bodyLineVertices[0] = xTopP;
bodyLineVertices[1] = yTopP;
bodyLineVertices[2] = zTopP;
bodyLineVertices[3] = xBottomP;
bodyLineVertices[4] = yBottomP;
bodyLineVertices[5] = zBottomP;
}
else if(i == nbFaceVertices/2)
{
bodyLineVertices[6] = xTopP;
bodyLineVertices[7] = yTopP;
bodyLineVertices[8] = zTopP;
bodyLineVertices[9] = xBottomP;
bodyLineVertices[10] = yBottomP;
bodyLineVertices[11] = zBottomP;
}
// Increase angle
angle += increment;
}
// Number of fans
nbFans = 1;
// Array containing the number of vertices for each fan (here we only have one fan triangle)
nbFanVertices = new int[1];
nbFanVertices[0] = nbFaceVertices;
// Array containing all the indices pointing the vertices in the array
// The resulting triangles must be indiced in order to keep the resulting
// normal from the triangles in a clockwise order.
fanIndices = new int[nbFaceVertices];
for(int i=0;i<nbFaceVertices;++i)
fanIndices[i] = 3*i;
// We fill the normal value
Point normalP(.0,.0,1.);
normalP=DirTrans*normalP;
normal[0] = normalP.GetX();
normal[1] = normalP.GetY();
normal[2] = normalP.GetZ();
// We create the top face
CAT3DPlanarFaceGP * topFace = new CAT3DPlanarFaceGP( topVertices, nbFaceVertices*3,
normal,
triangleIndices,
nbTriangles,
stripIndices,
nbStrips,
nbStripVertices,
fanIndices,
nbFans,
nbFanVertices);
// We create the line that bounds the face
CAT3DLineGP * topLine = new CAT3DLineGP(topVertices, nbFaceVertices, ALLOCATE, LINE_LOOP);
// Generate the fan indices
// As above, but we invert the indices in order to keep the resulting
// triangles in a clockwise order in respect to the normal
for(int i=0;i<nbFaceVertices;++i)
fanIndices[i] = 3*(nbFaceVertices-i-1);
// We fill the normal value
normalP=Point(.0,.0,-1.);
normalP=DirTrans*normalP;
normal[0] = normalP.GetX();
normal[1] = normalP.GetY();
normal[2] = normalP.GetZ();
// We create the bottom face
CAT3DPlanarFaceGP * bottomFace = new CAT3DPlanarFaceGP( bottomVertices, nbFaceVertices*3,
normal,
triangleIndices,
nbTriangles,
stripIndices,
nbStrips,
nbStripVertices,
fanIndices,
nbFans,
nbFanVertices);
// We create the line that bounds the face
CAT3DLineGP * bottomLine = new CAT3DLineGP(bottomVertices, nbFaceVertices, ALLOCATE, LINE_LOOP);
// We can now clear the indices arrays
CLEAR;
// Body face
nbStrips = 1;
nbStripVertices = new int[1];
stripIndices = new int[2*nbFaceVertices+2];
nbStripVertices[0] = 2*(nbFaceVertices+1);
// Generate the strip indices
for(int i=0;i<2*nbFaceVertices;++i)
stripIndices[i] = 3*i;
// Close the strip
stripIndices[2*nbFaceVertices] = 0;
stripIndices[2*nbFaceVertices+1] = 3;
// Generate the normals for each vertices of the body
for(int i=0;i<2*nbFaceVertices;++i)
{
float * vertex = &bodyVertices[3*i];
CATMathDirectionf normalDirection(CATMathPointf(0.0f, 0.0f, 0.0f), CATMathPointf(vertex[0], vertex[1], vertex[2]));
normalDirection.Normalize();
bodyNormals[3*i+0] = normalDirection.x;
bodyNormals[3*i+1] = normalDirection.y;
bodyNormals[3*i+2] = normalDirection.z;
}
// We create the body face
CAT3DFaceGP * bodyFace = new CAT3DFaceGP( bodyVertices, 2*nbFaceVertices*3,
bodyNormals, 2*nbFaceVertices*3,
triangleIndices,
nbTriangles,
stripIndices,
nbStrips,
nbStripVertices,
fanIndices,
nbFans,
nbFanVertices);
// We create the lines that bounds the body
CAT3DLineGP * bodyLine1 = new CAT3DLineGP(bodyLineVertices, 2, ALLOCATE, LINES);
CAT3DLineGP * bodyLine2 = new CAT3DLineGP(&bodyLineVertices[6], 2, ALLOCATE, LINES);
// We clear the indices arrays
CLEAR;
//箭头
float zTopTop=4.*radius+length;
float xyTop=3.*radius;
//Point CenterPoint(.0,.0,length);
Point FirstPoint(xyTop,xyTop,length),
SecondPoint(-xyTop,xyTop,length),
ThirdPoint(-xyTop,-xyTop,length),
FourthPoint(xyTop,-xyTop,length),
TopPoint(.0,.0,zTopTop);
FirstPoint=DirTrans*FirstPoint;
SecondPoint=DirTrans*SecondPoint;
ThirdPoint=DirTrans*ThirdPoint;
FourthPoint=DirTrans*FourthPoint;
TopPoint=DirTrans*TopPoint;
//四边形平面
float toptopface[12]={FirstPoint.GetX(),FirstPoint.GetY(),FirstPoint.GetZ(),
SecondPoint.GetX(),SecondPoint.GetY(),SecondPoint.GetZ(),
ThirdPoint.GetX(),ThirdPoint.GetY(),ThirdPoint.GetZ(),
FourthPoint.GetX(),FourthPoint.GetY(),FourthPoint.GetZ()
};
//四个三角形
float firsttri[9]={FirstPoint.GetX(),FirstPoint.GetY(),FirstPoint.GetZ(),
SecondPoint.GetX(),SecondPoint.GetY(),SecondPoint.GetZ(),
TopPoint.GetX(),TopPoint.GetY(),TopPoint.GetZ()};
float secondtri[9]={SecondPoint.GetX(),SecondPoint.GetY(),SecondPoint.GetZ(),
ThirdPoint.GetX(),ThirdPoint.GetY(),ThirdPoint.GetZ(),
TopPoint.GetX(),TopPoint.GetY(),TopPoint.GetZ()};
float thirdtri[9]={ThirdPoint.GetX(),ThirdPoint.GetY(),ThirdPoint.GetZ(),
FourthPoint.GetX(),FourthPoint.GetY(),FourthPoint.GetZ(),
TopPoint.GetX(),TopPoint.GetY(),TopPoint.GetZ()};
float fourthtri[9]={FourthPoint.GetX(),FourthPoint.GetY(),FourthPoint.GetZ(),
FirstPoint.GetX(),FirstPoint.GetY(),FirstPoint.GetZ(),
TopPoint.GetX(),TopPoint.GetY(),TopPoint.GetZ()};
normalP=Point(.0,.0,-1.);
normalP=DirTrans*normalP;
normal[0] = normalP.GetX();
normal[1] = normalP.GetY();
normal[2] = normalP.GetZ();
nbFans = 1;
nbFanVertices = new int[1];
nbFanVertices[0] = 4;
fanIndices = new int[4];
for(int i=0;i<4;++i)
fanIndices[i] = 3*(3-i);
CAT3DPlanarFaceGP * BigTopFace = new CAT3DPlanarFaceGP( toptopface, 12,
normal,
triangleIndices,
nbTriangles,
stripIndices,
nbStrips,
nbStripVertices,
fanIndices,
nbFans,
nbFanVertices);
CAT3DLineGP * BigTopLine = new CAT3DLineGP(toptopface, 4, ALLOCATE, LINE_LOOP);
CLEAR;
nbStrips = 1;
nbStripVertices = new int[1];
stripIndices = new int[3];
nbStripVertices[0] =3;
for(int i=0;i<3;++i)
stripIndices[i] = 3*i;
//FirstFace
normalP=Point(.0,.8,.6);
normalP=DirTrans*normalP;
normal[0] = normalP.GetX();
normal[1] = normalP.GetY();
normal[2] = normalP.GetZ();
CAT3DPlanarFaceGP * FirstFace = new CAT3DPlanarFaceGP( firsttri, 9,
normal,
triangleIndices,
nbTriangles,
stripIndices,
nbStrips,
nbStripVertices,
fanIndices,
nbFans,
nbFanVertices);
CAT3DLineGP * FirstLine = new CAT3DLineGP(firsttri, 3, ALLOCATE, LINE_LOOP);
//SecondFace
normalP=Point(-.8,.0,.6);
normalP=DirTrans*normalP;
normal[0] = normalP.GetX();
normal[1] = normalP.GetY();
normal[2] = normalP.GetZ();
CAT3DPlanarFaceGP * SecondFace = new CAT3DPlanarFaceGP( secondtri, 9,
normal,
triangleIndices,
nbTriangles,
stripIndices,
nbStrips,
nbStripVertices,
fanIndices,
nbFans,
nbFanVertices);
CAT3DLineGP * SecondLine = new CAT3DLineGP(secondtri, 3, ALLOCATE, LINE_LOOP);
//FirstFace
normalP=Point(.0,-.8,.6);
normalP=DirTrans*normalP;
normal[0] = normalP.GetX();
normal[1] = normalP.GetY();
normal[2] = normalP.GetZ();
CAT3DPlanarFaceGP * ThirdFace = new CAT3DPlanarFaceGP( thirdtri, 9,
normal,
triangleIndices,
nbTriangles,
stripIndices,
nbStrips,
nbStripVertices,
fanIndices,
nbFans,
nbFanVertices);
CAT3DLineGP * ThirdLine = new CAT3DLineGP(thirdtri, 3, ALLOCATE, LINE_LOOP);
//FirstFace
normalP=Point(.8,.0,.6);
normalP=DirTrans*normalP;
normal[0] = normalP.GetX();
normal[1] = normalP.GetY();
normal[2] = normalP.GetZ();
CAT3DPlanarFaceGP * FourthFace = new CAT3DPlanarFaceGP( fourthtri, 9,
normal,
triangleIndices,
nbTriangles,
stripIndices,
nbStrips,
nbStripVertices,
fanIndices,
nbFans,
nbFanVertices);
CAT3DLineGP * FourthLine = new CAT3DLineGP(fourthtri, 3, ALLOCATE, LINE_LOOP);
CLEAR;
// Delete the vertices and normal arrays
delete [] topVertices;
delete [] bottomVertices;
delete [] bodyVertices;
delete [] bodyNormals;
//
// Topological informations
// We can store topological informations on CATGraphicPrimitive objects
// If the visualization data is saved as a CGR file, topological data will
// be persistent in the CGR file
//
CATMathPoint center(0,0,0);
CATMathVector axis(0,0,1);
CATMathPoint startPoint,endPoint;
double dradius=(double)radius;
// Top face
CATGraphicPrimitive * gp=NULL;
gp = topFace;
CATVisMeasurableGP cylinderTop(gp);
cylinderTop.SetCylinder(center,axis,dradius);
// Bottom face
gp = bottomFace;
CATVisMeasurableGP cylinderBottom(gp);
cylinderBottom.SetCylinder(center,axis,dradius);
// Top line
gp = topLine;
CATVisMeasurableGP circleTop(gp);
circleTop.SetCircle(center,axis,dradius);
// Bottom line
gp = bottomLine;
CATVisMeasurableGP circleBottom(gp);
circleBottom.SetCircle(center,axis,dradius);
// Body face
gp = bodyFace;
CATVisMeasurableGP cylinderBody(gp);
cylinderBody.SetCylinder(center,axis,dradius);
// Body line 1
gp = bodyLine1;
startPoint.SetCoord(bodyLineVertices[0], bodyLineVertices[1], bodyLineVertices[2]);
endPoint.SetCoord (bodyLineVertices[3], bodyLineVertices[4], bodyLineVertices[5]);
CATVisMeasurableGP cylinderBodyLine1(gp);
cylinderBodyLine1.SetLine(startPoint,endPoint);
// Body line 2
gp = bodyLine2;
startPoint.SetCoord(bodyLineVertices[6], bodyLineVertices[7], bodyLineVertices[8]);
endPoint.SetCoord (bodyLineVertices[9], bodyLineVertices[10], bodyLineVertices[11]);
CATVisMeasurableGP cylinderBodyLine2(gp);
cylinderBodyLine2.SetLine(startPoint,endPoint);
//BigTopFace
gp=BigTopFace;
CATVisMeasurableGP BigTopF(gp);
BigTopF.SetCircle(center,axis,dradius);
//BigTopLine
gp=BigTopLine;
CATVisMeasurableGP BigTopL(gp);
BigTopL.SetCircle(center,axis,dradius);
gp=FirstFace;
CATVisMeasurableGP FirstF(gp);
FirstF.SetCircle(center,axis,dradius);
gp=FirstLine;
CATVisMeasurableGP FirstL(gp);
FirstL.SetCircle(center,axis,dradius);
gp=SecondFace;
CATVisMeasurableGP SecondF(gp);
SecondF.SetCircle(center,axis,dradius);
gp=SecondLine;
CATVisMeasurableGP SecondL(gp);
SecondL.SetCircle(center,axis,dradius);
gp=ThirdFace;
CATVisMeasurableGP ThirdF(gp);
ThirdF.SetCircle(center,axis,dradius);
gp=ThirdLine;
CATVisMeasurableGP ThirdL(gp);
ThirdL.SetCircle(center,axis,dradius);
gp=FourthFace;
CATVisMeasurableGP FourthF(gp);
FourthF.SetCircle(center,axis,dradius);
gp=FourthLine;
CATVisMeasurableGP FourthL(gp);
FourthL.SetCircle(center,axis,dradius);
_pCustomRep=CAT3DCustomRep::CreateRep();
CATGraphicAttributeSet tmpAtt;
tmpAtt.SetType(3); // Specifies that these faces are part of a volume
tmpAtt.SetColor(RED); // Give each face a specific color
tmpAtt.SetTransparentMode(1);
_pCustomRep->AddGP(topFace, tmpAtt);
_pCustomRep->AddGP(bottomFace, tmpAtt);
_pCustomRep->AddGP(bodyFace, tmpAtt);
_pCustomRep->AddGP(BigTopFace, tmpAtt);
_pCustomRep->AddGP(FirstFace, tmpAtt);
_pCustomRep->AddGP(SecondFace,tmpAtt);
_pCustomRep->AddGP(ThirdFace, tmpAtt);
_pCustomRep->AddGP(FourthFace, tmpAtt);
tmpAtt.SetColor(BLACK);
tmpAtt.SetThickness(2);
_pCustomRep->AddGP(topLine, tmpAtt);
_pCustomRep->AddGP(bottomLine, tmpAtt);
_pCustomRep->AddGP(bodyLine1, tmpAtt);
_pCustomRep->AddGP(bodyLine2, tmpAtt);
_pCustomRep->AddGP(BigTopLine, tmpAtt);
_pCustomRep->AddGP(FirstLine,tmpAtt);
_pCustomRep->AddGP(SecondLine, tmpAtt);
_pCustomRep->AddGP(ThirdLine, tmpAtt);
_pCustomRep->AddGP(FourthLine, tmpAtt);
效果如图: