+std::vector<std::vector<std::vector<double>>> ShowNPoints_Tools::GetOrderedPointsAroundPlane(std::vector<double> planeOrigin, std::vector<double> planeNormal, std::vector<double> rotAxis, std::vector<double> pX, std::vector<double> pY, std::vector<double> pZ){
+
+ std::vector<std::vector<double>> pointsOver, pointsUnder, pointsOn;
+ std::vector<double> point(3);
+ double rotatedNormal[3], vector1[3];
+ vtkMath::Cross(planeNormal.data(), rotAxis.data(), rotatedNormal);
+ vtkMath::Normalize(rotatedNormal);
+
+ bool changedSide = false;
+ int startingSide = -1; //-1 not started, 0 over, 1 under
+ int placedElements = 0;
+ for(int j = 0; j < pX.size(); j++){
+ point[0] = pX[j];
+ point[1] = pY[j];
+ point[2] = pZ[j];
+ vtkMath::Subtract(point.data(), planeOrigin.data(), vector1);
+ if(vtkMath::Dot(vector1, rotatedNormal) > 0){
+ if(!pointsUnder.empty()){
+ changedSide = true;
+ }
+ else {
+ startingSide = 0;
+ }
+
+ if(changedSide && startingSide == 0){
+ pointsOver.insert(pointsOver.begin()+placedElements, point);
+ placedElements++;
+ }
+ else{
+ pointsOver.push_back(point);
+ }
+ }
+ else if (vtkMath::Dot(vector1, rotatedNormal) < 0){
+ if(!pointsOver.empty())
+ {
+ changedSide = true;
+ }
+ else startingSide = 1;
+
+ if(changedSide && startingSide == 1){
+ pointsUnder.insert(pointsUnder.begin()+placedElements, point);
+ placedElements++;
+ }
+ else{
+ pointsUnder.push_back(point);
+ }
+ }
+ else{
+ pointsOn.push_back(point);
+ }
+ }
+ ////////
+ /// Check direction of points and reverse if needed.
+ /// Always follows axis vector direction
+ ////////
+ if(pointsUnder.size() > 2){
+ vtkMath::Subtract(pointsUnder.front(), pointsUnder.back(), vector1);
+ double dot = vtkMath::Dot(vector1, rotAxis.data());
+ if(dot < 0){
+ std::reverse(pointsUnder.begin(), pointsUnder.end());
+ if(startingSide == 1 && !pointsOn.empty()){
+ std::reverse(pointsOn.begin(), pointsOn.end());
+ }
+ }
+ }
+ if(pointsOver.size() > 2){
+ vtkMath::Subtract(pointsOver.front(), pointsOver.back(), vector1);
+ double dot = vtkMath::Dot(vector1, rotAxis.data());
+ if(dot < 0){
+ std::reverse(pointsOver.begin(), pointsOver.end());
+ if(startingSide == 0 && !pointsOn.empty()){
+ std::reverse(pointsOn.begin(), pointsOn.end());
+ }
+ }
+ }
+
+ std::vector<std::vector<std::vector<double>>> results = {pointsOver, pointsUnder, pointsOn};
+ return results;
+}
+
+std::vector<double> ShowNPoints_Tools::GetPlaneNormalFromPointsRefPoint(std::vector<double> pointsX, std::vector<double> pointsY, std::vector<double> pointsZ, std::vector<double> refPoint)
+{
+ double vector1[3], vector2[3], planeNormal[3];
+ int idPoint2, idPoint3;
+ idPoint2 = ((int)pointsX.size()/3)-1;
+ idPoint3 = ((int)pointsX.size()/2)+1;
+
+ vector1[0] = pointsX[idPoint2]-refPoint[0];
+ vector1[1] = pointsY[idPoint2]-refPoint[1];
+ vector1[2] = pointsZ[idPoint2]-refPoint[2];
+
+ vector2[0] = pointsX[idPoint3]-refPoint[0];
+ vector2[1] = pointsY[idPoint3]-refPoint[1];
+ vector2[2] = pointsZ[idPoint3]-refPoint[2];
+
+ vtkMath::Cross(vector1, vector2, planeNormal);
+ vtkMath::Normalize(planeNormal);
+
+ std::vector<double> result(std::begin(planeNormal), std::end(planeNormal));
+ return result;
+}
+
+std::vector<double> ShowNPoints_Tools::GetProjectionPointOnAxis(double pointToProject[3], double originAxis[3], double axisDir[3])
+{
+ double projectionVect[3], vectorToPoint[3], pointProjected[3];
+ vtkMath::Subtract(pointToProject, originAxis, vectorToPoint);
+
+ vtkMath::ProjectVector(vectorToPoint, axisDir, projectionVect);
+ vtkMath::Add(originAxis, projectionVect, pointProjected);
+
+ std::vector<double> result(std::begin(pointProjected), std::end(pointProjected));
+ return result;
+}
+
+