From a4f645c6daf10182681a5bbad23d5fa62f20b34a Mon Sep 17 00:00:00 2001
From: Eduardo DAVILA <davila@creatis.insa-lyon.fr>
Date: Mon, 27 Jun 2022 11:38:22 +0200
Subject: [PATCH] #3486 ShowNPoints bug insert first/last point

---
 .../wxWindows/widgets/ModelShowNPoints.cxx    | 67 ++++++++++++++++---
 .../wxWindows/widgets/ModelShowNPoints.h      |  2 +-
 2 files changed, 60 insertions(+), 9 deletions(-)

diff --git a/lib/maracasVisuLib/src/interface/wxWindows/widgets/ModelShowNPoints.cxx b/lib/maracasVisuLib/src/interface/wxWindows/widgets/ModelShowNPoints.cxx
index c3c0672..f36297f 100644
--- a/lib/maracasVisuLib/src/interface/wxWindows/widgets/ModelShowNPoints.cxx
+++ b/lib/maracasVisuLib/src/interface/wxWindows/widgets/ModelShowNPoints.cxx
@@ -125,9 +125,10 @@ void ModelShowNPoints::AddPoint(int x, int y, int z, std::string label)
 }
 
 //------------------------------------------------------------------------
-double ModelShowNPoints::Distance(double dX0, double dY0, double dZ0, double dX1, double dY1, double dZ1)//CFT
+double ModelShowNPoints::DistanceSQ(double dX0, double dY0, double dZ0, double dX1, double dY1, double dZ1)//CFT
 {
-    return sqrt((dX1 - dX0)*(dX1 - dX0) + (dY1 - dY0)*(dY1 - dY0) + (dZ1 - dZ0)*(dZ1 - dZ0));
+//    return sqrt((dX1 - dX0)*(dX1 - dX0) + (dY1 - dY0)*(dY1 - dY0) + (dZ1 - dZ0)*(dZ1 - dZ0));
+        return (dX1 - dX0)*(dX1 - dX0) + (dY1 - dY0)*(dY1 - dY0) + (dZ1 - dZ0)*(dZ1 - dZ0);
 }
 
 //------------------------------------------------------------------------
@@ -137,19 +138,19 @@ int ModelShowNPoints::InsertPoint(int x, int y, int z, std::string label)
 	{
 		std::vector<int> dTotal;
 		int pos = 1;
-		int a,b,res;
-		
+		double a,b,c,res;
+        int i,j;
 		//Calcule distance for each pair of points
-		for(int i = 0; i<(int)lstPointsX.size()-1 ; i++)
+		for(i = 0; i<(int)lstPointsX.size()-1 ; i++)
 		{
-				a = Distance(x, y, z, lstPointsX[i], lstPointsY[i], lstPointsZ[i]);
-				b = Distance(x, y, z, lstPointsX[i+1], lstPointsY[i+1], lstPointsZ[i+1]);
+				a = DistanceSQ(x, y, z, lstPointsX[i], lstPointsY[i], lstPointsZ[i]);
+				b = DistanceSQ(x, y, z, lstPointsX[i+1], lstPointsY[i+1], lstPointsZ[i+1]);
 				res = a + b;		
 				dTotal.push_back (res);		
 		}
 		//Gets the smallest distance 
 		int smallTMP = dTotal[0];
-	 	for (int j = 0; j < (int) dTotal.size(); j++)
+	 	for (j = 0; j < (int) dTotal.size(); j++)
 		{
 			  if(dTotal[j]<smallTMP)
 			  {
@@ -158,6 +159,56 @@ int ModelShowNPoints::InsertPoint(int x, int y, int z, std::string label)
 			  }
 		}
 		
+        
+        // In open contour case
+        if (lstPointsX.size()==2)
+        {
+            double cx,cy,cz,r1,r2;
+            i  = 0;
+            cx = (lstPointsX[i]+lstPointsX[i+1]) / 2;
+            cy = (lstPointsY[i]+lstPointsY[i+1]) / 2;
+            cz = (lstPointsZ[i]+lstPointsZ[i+1]) / 2;
+            r1 = DistanceSQ( cx,cy,cz,x,y,z );
+            r2 = DistanceSQ( cx,cy,cz,lstPointsX[i], lstPointsY[i], lstPointsZ[i] );
+            if (r1<r2) // inside circle
+            {
+                pos=1;
+            } else {   // outside circle
+                if (a<b)  // befor first point
+                {
+                    pos=0;
+                } else {  // after second point
+                pos=2;
+                }
+            }
+
+        }
+        if (lstPointsX.size()>2)
+        {
+            double r3;
+            if ( pos==1)  // first point of the list
+            {
+                i = 0;
+                a = DistanceSQ(x, y, z, lstPointsX[i], lstPointsY[i], lstPointsZ[i]);
+                b = DistanceSQ(x, y, z, lstPointsX[i+1], lstPointsY[i+1], lstPointsZ[i+1]);
+                r3 = DistanceSQ( lstPointsX[i], lstPointsY[i], lstPointsZ[i],lstPointsX[i+1], lstPointsY[i+1], lstPointsZ[i+1] );
+                if (b>r3) // outside circle
+                {
+                    pos = 0;
+                }
+            }
+            if (pos==lstPointsX.size()-1 )  // last point of the list
+            {
+                i = lstPointsX.size()-2;
+                r3 = DistanceSQ( lstPointsX[i], lstPointsY[i], lstPointsZ[i],lstPointsX[i+1], lstPointsY[i+1], lstPointsZ[i+1] );
+                if (a>r3) // outside circle
+                {
+                    pos = pos+1;
+                }
+            }
+        }
+
+        
 		std::vector<int>::iterator it;
 		//Insert the point in the list of points
 		it = lstPointsX.begin();
diff --git a/lib/maracasVisuLib/src/interface/wxWindows/widgets/ModelShowNPoints.h b/lib/maracasVisuLib/src/interface/wxWindows/widgets/ModelShowNPoints.h
index 5f01f16..2dbf923 100644
--- a/lib/maracasVisuLib/src/interface/wxWindows/widgets/ModelShowNPoints.h
+++ b/lib/maracasVisuLib/src/interface/wxWindows/widgets/ModelShowNPoints.h
@@ -20,7 +20,7 @@ class ModelShowNPoints
 	  std::string 				GetIdLabel(int id);
 	  std::vector<std::string> 	GetLstLabels();
 	  void 						AddPoint(int x, int y, int z, std::string label);
-	  double 					Distance(double dX0, double dY0, double dZ0, double dX1, double dY1, double dZ1);
+	  double 					DistanceSQ(double dX0, double dY0, double dZ0, double dX1, double dY1, double dZ1);
 	  int 						InsertPoint(int x, int y, int z, std::string label);
 	  void						SavePoints(std::string filename);
       void                      SavePoints_(FILE* ff);
-- 
2.49.0