I want to find the inner polydata which are surrounded by six planes in the above image.
So the intersect point of the three planes that intersect is important.
How to find the intersect point of the three planes?
We know the mathematical expression for a plane has the following format.
The vector (a, b, c) is the normal of the plane, the point is the origin of the plane.
The expression can be converted to a simpler equation.
The three planes can be described as the following equation set.
Let’s use the matrix to represent it.
So the intersect point can be calculated by the three origin points and normal vectors.
The eight corners described in the code snippet has same order as the following image, ignore the sphere and axis.
Code snippet:
PointStruct ComputeIntersectPt(vtkSmartPointer<vtkPlane> plane1, vtkSmartPointer<vtkPlane> plane2, vtkSmartPointer<vtkPlane> plane3)
{
PointStruct origin1( plane1->GetOrigin() );
PointStruct normal1( plane1->GetNormal() );
PointStruct origin2( plane2->GetOrigin() );
PointStruct normal2( plane2->GetNormal() );
PointStruct origin3( plane3->GetOrigin() );
PointStruct normal3( plane3->GetNormal() );
double D1 = normal1.Dot(origin1);
double D2 = normal2.Dot(origin2);
double D3 = normal3.Dot(origin3);
PointStruct DVector( D1, D2, D3 );
PointStruct result;
vtkSPtrNew( AMatrix, vtkMatrix3x3 );
for( int col = 0; col < 3; col++ )
{
AMatrix->SetElement( 0, col, normal1[col] );
}
for( int col = 0; col < 3; col++ )
{
AMatrix->SetElement( 1, col, normal2[col] );
}
for( int col = 0; col < 3; col++ )
{
AMatrix->SetElement( 2, col, normal3[col] );
}
AMatrix->Invert();
AMatrix->MultiplyPoint( DVector.point, result.point );
return result;
}
// ============== create polydata from the eight corner points =================
void InsertCell(vtkSmartPointer<vtkCellArray> cell, vtkIdType *index)
{
vtkIdType pts1[3] = { index[0], index[2], index[1] };
cell->InsertNextCell( 3, pts1 );
vtkIdType pts2[3] = { index[2], index[0], index[3] };
cell->InsertNextCell( 3, pts2 );
}
void GenerateShell()
{
FindBottomTopPlane( m_BottomPlane, m_TopPlane );
FindLeftRightSidePlanes( m_LeftPlane, m_RightPlane );
ShowPlane( m_BottomPlane );
ShowPlane( m_TopPlane );
ShowPlane( m_LeftPlane );
ShowPlane( m_RightPlane );
ShowPlane( m_BackPlane );
PointStruct pt[8];
pt[0] = ComputeIntersectPt( m_FrontPlane, m_LeftPlane, m_BottomPlane );
pt[1] = ComputeIntersectPt( m_FrontPlane, m_RightPlane, m_BottomPlane );
pt[2] = ComputeIntersectPt( m_BackPlane, m_RightPlane, m_BottomPlane );
pt[3] = ComputeIntersectPt( m_BackPlane, m_LeftPlane, m_BottomPlane );
pt[4] = ComputeIntersectPt( m_FrontPlane, m_LeftPlane, m_TopPlane );
pt[5] = ComputeIntersectPt( m_FrontPlane, m_RightPlane, m_TopPlane );
pt[6] = ComputeIntersectPt( m_BackPlane, m_RightPlane, m_TopPlane );
pt[7] = ComputeIntersectPt( m_BackPlane, m_LeftPlane, m_TopPlane );
vtkSPtrNew( pts, vtkPoints );
for( int i = 0; i < 8; ++i )
{
pts->InsertNextPoint( pt[i].point );
}
vtkSPtrNew( pd, vtkPolyData );
pd->SetPoints( pts );
vtkSPtrNew( cells, vtkCellArray );
vtkIdType index0[4] = { 0, 1, 2, 3 }; // down
InsertCell( cells, index0 );
vtkIdType index1[4] = { 4, 7, 6, 5 }; // up
InsertCell( cells, index1 );
vtkIdType index2[4] = { 0, 4, 5, 1 }; // front
InsertCell( cells, index2 );
vtkIdType index3[4] = { 3, 2, 6, 7 }; // back
InsertCell( cells, index3 );
vtkIdType index4[4] = { 0, 3, 7, 4 }; // left
InsertCell( cells, index4 );
vtkIdType index5[4] = { 1, 5, 6, 2 }; // right
InsertCell( cells, index5 );
pd->SetPolys( cells );
m_ShellActor->GetMapper()->SetInputDataObject( pd );
m_Render->AddActor( m_ShellActor );
}
// ====================== hide all debug planes ==============================
void OnKeyPressEvent()
{
vtkRenderWindowInteractor* interactor = GetInteractor();
char *sym = interactor->GetKeySym();
QString keyName(sym);
int isCtrl = interactor->GetControlKey();
LOG( INFO, "keyName: ", keyName.toStdString(), ", isCtrl: ", isCtrl );
if( isCtrl && (keyName == "K" || keyName == "k") )
{
ShowDebugActors( false );
}
}
m_EventConnections->Connect(ui->qvtkWidget->GetRenderWindow()->GetInteractor(),
vtkCommand::KeyPressEvent,
this,
SLOT(OnKeyPressEvent()));