几何尺寸与公差论坛------致力于产品几何量公差标准GD&T (GDT:ASME)|New GPS(ISO)研究/CAD设计/CAM加工/CMM测量

几何尺寸与公差论坛------致力于产品几何量公差标准GD&T (GDT:ASME)|New GPS(ISO)研究/CAD设计/CAM加工/CMM测量 (http://www.dimcax.com/hust/index.php)
-   DirectDWG (http://www.dimcax.com/hust/forumdisplay.php?f=89)
-   -   【转帖】olerance Issue In Intersectwith (http://www.dimcax.com/hust/showthread.php?t=18794)

yang686526 2009-05-07 05:09 PM

【转帖】olerance Issue In Intersectwith
 
tolerance issue in intersectwith
tolerance issue in intersectwith
hi,
i have an issue while giving the tolerance value in the odgelineseg2d::intersectwith() method
i have 2 odgelineseg2d objects seg1 and seg2.
i need to find if there is overlap between them using the tolerance value "dtolerance", so that all overlap
values below the "dtolerance" is detected.
odgelineseg2d seg1(lp1,lp2);
odgelineseg2d seg2(lp3,lp4);
odgetol tol(dtolerance);
odgepoint2d geintpt;
bool bvalue = seg1.intersectwith(seg2,geintpt,tol);
before calling the function i determined the segments as overlapping with a value of 4 units(minimum).
after execution, with tolerance == 0 i get the correct result that there is overlap and the intersection point.
but , with tolerance == 1 i get the wrong result that there is no overlap , and this is true for all higher values of tolerances. ( actual overlap = 4 )
ideally, till the value of tolerance remains below 4, the method should detect an overlap.
this shows that the function ignores overlaps even when considerably low tolerance values are provided.
can anybody tell me what are the norms to pass the tolerance arguments to this method..? in your opinion is there a fix for my issue..?
thanks,
abhi

hi,
yes, you are right. tolerance in intersectwith() method can't be used for overlap calculation.
really for overlap calculation must be implemented special method into odgelinearent2d classes:
code:
/*
virtual bool overlap (const odgelinearent2d& line, odgelinearent2d*& overlap,
const odgetol& tol = odgecontext::gtol) const = 0;
*/, but currently it is not implemented. ge library improvements planned in future.
temporarily you can compute distance between line segments manually, using, for example, following function (or your own):
code:
/* amark : untested */
double odgelinesegdistance(const odgelineseg2d &seg1, const odgelineseg2d &seg2, odgepoint2d *ppt1 = null, odgepoint2d *ppt2 = null)
{
odgevector2d seg1_dir = seg1.endpoint() - seg1.startpoint();
odgevector2d seg2_dir = seg2.endpoint() - seg2.startpoint();
odgevector2d diff = seg1.startpoint() - seg2.startpoint();
double a00 = seg1_dir.lengthsqrd();
double a01 = -seg1_dir.dotproduct(seg2_dir);
double a11 = seg2_dir.lengthsqrd();
double b0 = diff.dotproduct(seg1_dir);
double c = diff.lengthsqrd();
double det = fabs(a00 * a11 - a01 * a01);
double b1, s, t, sqrdist, tmp;
if (det >= odgetol().equalvector()) // @@@todo: add external tolerance later
{
// line segments are not parallel
b1 = -diff.dotproduct(seg2_dir);
s = a01 * b1 - a11 * b0;
t = a01 * b0 - a00 * b1;
if (s >= 0.0)
{
if (s <= det)
{
if (t >= 0.0)
{
if (t <= det)
{
double invdet = 1.0 / det;
s *= invdet;
t *= invdet;
sqrdist = s * (a00 * s + a01 * t + 2.0 * b0) + t * (a01 * s + a11 * t + 2.0 * b1) + c;
}
else
{
t = 1.0;
tmp = a01 + b0;
if (tmp >= 0.0)
{
s = 0.0;
sqrdist = a11 + 2.0 * b1 + c;
}
else if (-tmp >= a00)
{
s = 1.0;
sqrdist = a00 + a11 + c + 2.0 * (b1 + tmp);
}
else
{
s = -tmp / a00;
sqrdist = tmp * s + a11 + 2.0 * b1 + c;
}
}
}
else
{
t = 0.0;
if (b0 >= 0.0)
{
s = 0.0;
sqrdist = c;
}
else if (-b0 >= a00)
{
s = 1.0;
sqrdist = a00 + 2.0 * b0 + c;
}
else
{
s = -b0 / a00;
sqrdist = b0 * s + c;
}
}
}
else
{
if (t >= 0.0)
{
if (t <= det)
{
s = 1.0;
tmp = a01 + b1;
if (tmp >= 0.0)
{
t = 0.0;
sqrdist = a00 + 2.0 * b0 + c;
}
else if (-tmp >= a11)
{
t = 1.0;
sqrdist = a00 + a11 + c + 2.0 * (b0 + tmp);
}
else
{
t = -tmp / a11;
sqrdist = tmp * t + a00 + 2.0 * b0 + c;
}
}
else
{
tmp = a01 + b0;
if (-tmp <= a00)
{
t = 1.0;
if (tmp >= 0.0)
{
s = 0.0f;
sqrdist = a11 + 2.0 * b1 + c;
}
else
{
s = -tmp / a00;
sqrdist = tmp * s + a11 + 2.0 * b1 + c;
}
}
else
{
s = 1.0;
tmp = a01 + b1;
if (tmp >= 0.0)
{
t = 0.0;
sqrdist = a00 + 2.0 * b0 + c;
}
else if (-tmp >= a11)
{
t = 1.0;
sqrdist = a00 + a11 + c + 2.0 * (b0 + tmp);
}
else
{
t = -tmp / a11;
sqrdist = tmp * t + a00 + 2.0 * b0 + c;
}
}
}
}
else
{
if (-b0 < a00)
{
t = 0.0;
if (b0 >= 0.0)
{
s = 0.0;
sqrdist = c;
}
else
{
s = -b0 / a00;
sqrdist = b0 * s + c;
}
}
else
{
s = 1.0;
tmp = a01 + b1;
if (tmp >= 0.0)
{
t = 0.0;
sqrdist = a00 + 2.0 * b0 + c;
}
else if (-tmp >= a11)
{
t = 1.0;
sqrdist = a00 + a11 + c + 2.0 * (b0 + tmp);
}
else
{
t = -tmp / a11;
sqrdist = tmp * t + a00 + 2.0 * b0 + c;
}
}
}
}
}
else
{
if (t >= 0.0)
{
if (t <= det)
{
s = 0.0;
if (b1 >= 0.0)
{
t = 0.0;
sqrdist = c;
}
else if (-b1 >= a11)
{
t = 1.0;
sqrdist = a11 + 2.0 * b1 + c;
}
else
{
t = -b1 / a11;
sqrdist = b1 * t + c;
}
}
else
{
tmp = a01 + b0;
if (tmp < 0.0)
{
t = 1.0;
if (-tmp >= a00)
{
s = 1.0;
sqrdist = a00 + a11 + c + 2.0 * (b1 + tmp);
}
else
{
s = -tmp / a00;
sqrdist = tmp * s + a11 + 2.0 * b1 + c;
}
}
else
{
s = 0.0;
if (b1 >= 0.0)
{
t = 0.0;
sqrdist = c;
}
else if (-b1 >= a11)
{
t = 1.0;
sqrdist = a11 + 2.0 * b1 + c;
}
else
{
t = -b1 / a11;
sqrdist = b1 * t + c;
}
}
}
}
else
{
if (b0 < 0.0)
{
t = 0.0;
if (-b0 >= a00)
{
s = 1.0;
sqrdist = a00 + 2.0 * b0 + c;
}
else
{
s = -b0 / a00;
sqrdist = b0 * s + c;
}
}
else
{
s = 0.0;
if (b1 >= 0.0)
{
t = 0.0;
sqrdist = c;
}
else if (-b1 >= a11)
{
t = 1.0;
sqrdist = a11 + 2.0 * b1 + c;
}
else
{
t = -b1 / a11;
sqrdist = b1 * t + c;
}
}
}
}
}
else
{
// line segments are parallel
if (a01 > 0.0)
{
if (b0 >= 0.0)
{
s = 0.0;
t = 0.0;
sqrdist = c;
}
else if (-b0 <= a00)
{
s = -b0 / a00;
t = 0.0;
sqrdist = b0 * s + c;
}
else
{
b1 = -diff.dotproduct(seg2_dir);
s = 1.0;
tmp = a00 + b0;
if (-tmp >= a01)
{
t = 1.0;
sqrdist = a00 + a11 + c + 2.0 * (a01 + b0 + b1);
}
else
{
t = -tmp / a01;
sqrdist = a00 + 2.0 * b0 + c + t * (a11 * t + 2.0 * (a01 + b1));
}
}
}
else
{
if (-b0 >= a00)
{
s = 1.0;
t = 0.0;
sqrdist = a00 + 2.0 * b0 + c;
}
else if (b0 <= 0.0)
{
s = -b0 / a00;
t = 0.0;
sqrdist = b0 * s + c;
}
else
{
b1 = -diff.dotproduct(seg2_dir);
s = 0.0;
if (b0 >= -a01)
{
t = 1.0;
sqrdist = a11 + 2.0 * b1 + c;
}
else
{
t = -b0 / a01;
sqrdist = c + t * (2.0 * b1 + a11 * t);
}
}
}
}
// point on seg1 = startpoint + direction * s;
if (ppt1)
*ppt1 = seg1.startpoint() + seg1_dir * s;
// point on seg2 = startpoint + direction * t;
if (ppt2)
*ppt2 = seg2.startpoint() + seg2_dir * t;
// sqrlen = fabs(sgrdist)
return sqrt(sqrdist);
thank you, mark, your reply was helpful.
abhi


所有的时间均为北京时间。 现在的时间是 11:31 PM.