{
}
+//-------------------------------------------------------------------
void manualViewBaseContour::AutomaticOpenCloseContour() // virtual
{
}
+
+
+#define _VECTOR_SUB( a ,b ,r ) \
+ r[0] = a[0]-b[0]; \
+ r[1] = a[1]-b[1]; \
+ r[2] = a[2]-b[2];
+
+#define _VECTOR_MODULE( a ) sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2] )
+
+#define _VECTOR_DOT( a , b ) a[0]*b[0] + a[1]*b[1] + a[2]*b[2]
+
+#define _VECTOR_CROSS( a ,b ,r ) \
+ r[0] = a[1] * b[2] - a[2] * b[1]; \
+ r[1] = a[2] * b[0] - a[0] * b[2]; \
+ r[2] = a[0] * b[1] - a[1] * b[0];
+
+//-------------------------------------------------------------------
+double manualViewBaseContour::DistanceToSegment( double v[3], double a[3], double b[3] )
+{
+ // https://www.geeksforgeeks.org/program-dot-product-cross-product-two-vector/
+
+ double ab[3]; _VECTOR_SUB(b,a, ab )
+ double av[3]; _VECTOR_SUB(v,a, av )
+ if (_VECTOR_DOT(av,ab) <= 0.0) // Point is lagging behind start of the segment, so perpendicular distance is not viable.
+ {
+ return _VECTOR_MODULE(av) ; // Use distance to start of segment instead.
+ }
+ double bv[3]; _VECTOR_SUB(v,b,bv )
+ if (_VECTOR_DOT(bv,ab) >= 0.0) // Point is advanced past the end of the segment, so perpendicular distance is not viable.
+ {
+ return _VECTOR_MODULE(bv) ; // Use distance to end of the segment instead.
+ }
+ double c[3]; _VECTOR_CROSS(ab,av,c);
+ return _VECTOR_MODULE(c) / _VECTOR_MODULE(ab); // Perpendicular distance of point to segment.
+}
}
}
-
-#define _VECTOR_SUB( a ,b ,r ) \
- r[0] = a[0]-b[0]; \
- r[1] = a[1]-b[1]; \
- r[2] = a[2]-b[2];
-
-#define _VECTOR_MODULE( a ) sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2] )
-
-#define _VECTOR_DOT( a , b ) a[0]*b[0] + a[1]*b[1] + a[2]*b[2]
-
-#define _VECTOR_CROSS( a ,b ,r ) \
- r[0] = a[1] * b[2] - a[2] * b[1]; \
- r[1] = a[2] * b[0] - a[0] * b[2]; \
- r[2] = a[0] * b[1] - a[1] * b[0];
-
-
-double _distanceToSegment( double v[3], double a[3], double b[3] )
-{
- // https://www.geeksforgeeks.org/program-dot-product-cross-product-two-vector/
-
- double ab[3]; _VECTOR_SUB(b,a, ab )
- double av[3]; _VECTOR_SUB(v,a, av )
- if (_VECTOR_DOT(av,ab) <= 0.0) // Point is lagging behind start of the segment, so perpendicular distance is not viable.
- {
- return _VECTOR_MODULE(av) ; // Use distance to start of segment instead.
- }
- double bv[3]; _VECTOR_SUB(v,b,bv )
- if (_VECTOR_DOT(bv,ab) >= 0.0) // Point is advanced past the end of the segment, so perpendicular distance is not viable.
- {
- return _VECTOR_MODULE(bv) ; // Use distance to end of the segment instead.
- }
- double c[3]; _VECTOR_CROSS(ab,av,c);
- return _VECTOR_MODULE(c) / _VECTOR_MODULE(ab); // Perpendicular distance of point to segment.
-}
-
// ----------------------------------------------------------------------------
bool manualViewContour::ifTouchContour(int x,int y,int z)
{
double d1,d2,d3;
TransfromCoordViewWorld(xx,yy,zz);
//EED 27 sep 2006
- xx = xx * _spc[0];
- yy = yy * _spc[1];
- zz = zz * _spc[2];
- pp[0]=xx;
- pp[1]=yy;
- pp[2]=zz;
- if ( (xx>=_minX) && (yy>=_minY) && (xx<=_maxX) && (yy<=_maxY))
- { // inside the boundaring box
- double dirVec[3];
- double num;
- double k;
- double den;
- double projX;
- double projY;
- double projZ;
+ xx = xx * _spc[0];
+ yy = yy * _spc[1];
+ zz = zz * _spc[2];
+ pp[0] = xx;
+ pp[1] = yy;
+ pp[2] = zz;
+ double DeltaDistancePointToLine = GetWidthLine() +0.25;
+
+ if ( (xx>=_minX) && (yy>=_minY) && (xx<=_maxX) && (yy<=_maxY)) // inside the boundaring box
+ {
if ( ShowLineVersion()==true )
{
_pts->GetPoint(0, ppA);
_pts->GetPoint(1, ppB);
+ /* V1
+ double dirVec[3];
+ double num;
+ double k;
+ double den;
+ double projX;
+ double projY;
+ double projZ;
// direction of the segment
dirVec[0] = ppB[0] - ppA[0];
dirVec[1] = ppB[1] - ppA[1];
dirVec[2] = ppB[2] - ppA[2];
// proj = mpA + k*dirVec
den = 0.0 ;
-
num = dirVec[0]*( xx-ppA[0] );
num = num + dirVec[1]*( yy-ppA[1] );
num = num + dirVec[2]*( zz-ppA[2] );
-
den=dirVec[0]*dirVec[0] + dirVec[1]*dirVec[1] + dirVec[2]*dirVec[2];
if (den!=0)
{
projX = ppA[0] + k*dirVec[0];
projY = ppA[1] + k*dirVec[1];
projZ = ppA[2] + k*dirVec[2];
-
// distance [projX,projY,projZ] and (xx,yy,zz]
d1 = sqrt( (projX-xx)*(projX-xx) + (projY-yy)*(projY-yy) +(projZ-zz)*(projZ-zz) );
if (d1<=1)
{
result=true;
} // if d1
-
+ */
+ if ( DistanceToSegment(pp,ppA,ppB) <= DeltaDistancePointToLine )
+ {
+ result = true;
+ } // if DistanceToSegment
} else {
unsigned int i, nps,nps_t;
nps = _sizePointsContour;
} else {
nps_t = nps-1;
} // if close
-
for( i = 0; i < nps_t; i++ )
{
_pts->GetPoint(i%nps, ppA);
_pts->GetPoint((i+1)%nps, ppB);
-
/* V1 working but not proportional distance throw al contour
d1 = sqrt( (ppA[0]-xx)*(ppA[0]-xx) + (ppA[1]-yy)*(ppA[1]-yy) + (ppA[2]-zz)*(ppA[2]-zz));
d2 = sqrt( (ppB[0]-xx)*(ppB[0]-xx) + (ppB[1]-yy)*(ppB[1]-yy) + (ppB[2]-zz)*(ppB[2]-zz));
i = nps;
} // if
*/
-
- /* V2 not working
-
- // direction of the segment
- dirVec[0] = ppB[0] - ppA[0];
- dirVec[1] = ppB[1] - ppA[1];
- dirVec[2] = ppB[2] - ppA[2];
- // proj = mpA + k*dirVec
- den = 0.0 ;
-
- num = dirVec[0]*( xx-ppA[0] );
- num = num + dirVec[1]*( yy-ppA[1] );
- num = num + dirVec[2]*( zz-ppA[2] );
-
- den=dirVec[0]*dirVec[0] + dirVec[1]*dirVec[1] + dirVec[2]*dirVec[2];
- if (den!=0)
- {
- k = num/den;
- } else {
- k = 99999999;
- }
- // projection of th point xx,yy,zz in segment mpA,mpB
- projX = ppA[0] + k*dirVec[0];
- projY = ppA[1] + k*dirVec[1];
- projZ = ppA[2] + k*dirVec[2];
-
- // distance [projX,projY,projZ] and (xx,yy,zz]
- d1 = sqrt( (projX-xx)*(projX-xx) + (projY-yy)*(projY-yy) +(projZ-zz)*(projZ-zz) );
-
- printf("EED manualViewContour::ifTouchContour flag 2 %d point=%f %f %f d1=%f\n", nps_t , xx,yy,zz, d1);
- printf("EED A=%f %f %f B=%f %f %f\n", ppA[0], ppA[1], ppA[2], ppB[0],ppB[1],ppB[2] );
-
- if (d1<=1)
- {
- result = true;
- i = nps;
- } // if d1
-*/
- // V3 ok in mathematical point of view. Missing optimization c++
- if ( _distanceToSegment(pp,ppA,ppB) <=1 )
+ // V3 ok
+ if ( DistanceToSegment(pp,ppA,ppB) <= DeltaDistancePointToLine )
{
result = true;
i = nps;
- }
-
+ } // if DistanceToSegment
} // for i
} // if GetSizeLstPoints()==2
} // if min max
-
return result;
}