我正在使用CGAL进行几何计算。我需要精确的算术运算(即加法,减法,乘法,除法)来计算。所以到目前为止我的最佳解决方案是以下数字类型:
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef CGAL::Lazy_exact_nt<CGAL::Quotient<CGAL::MP_Float> > NT;
然后我应该能够执行精确的算术运算,如:
NT a, b, c;
a = b + c;
现在我有点担心精确算术的性能开销与“标准”浮点算法相比。与双倍相比,CGAL的确切数字类型的性能有多差?是否存在一个上限,表明性能开销有多大?
编辑我应该更多地描述我需要实现的目标。我想在3D空间中实现三角形/三角形分割。因此,如果两个三角形相交,那么我想在它们的交叉线上分割它们。 当我有非常小的三角形或两个三角形的交点非常小时会出现问题。这导致舍入错误,我的程序崩溃。我试图使用容差值来管理它,但这仅在99%的时间内有效。我想编写100%有效的软件,所以我真的需要精确的计算。 我其实只需要两件事:
关于交叉线caclulation,我有这样的计算:
public Vector3m ComputeLineIntersection(IntersectionLine& otherLine)
{
//x = x1 + a1*t = x2 + b1*s
//y = y1 + a2*t = y2 + b2*s
//z = z1 + a3*t = z2 + b3*s
Vector3m linePoint = otherLine._point;
Vector3m lineDirection = otherLine._direction;
NT t;
if ((_direction.Y * lineDirection.X - _direction.X * lineDirection.Y) != 0)
{
t = (-_point.Y * lineDirection.X + linePoint.Y * lineDirection.X + lineDirection.Y * _point.X - lineDirection.Y * linePoint.X) / (_direction.Y * lineDirection.X - _direction.X * lineDirection.Y);
}
else if ((-_direction.X * lineDirection.Z + _direction.Z * lineDirection.X) != 0)
{
t = -(-lineDirection.Z * _point.X + lineDirection.Z * linePoint.X + lineDirection.X * _point.Z - lineDirection.X * linePoint.Z) / (-_direction.X * lineDirection.Z + _direction.Z * lineDirection.X);
}
else if ((-_direction.Z*lineDirection.Y + _direction.Y*lineDirection.Z) != 0)
{
t = (_point.Z*lineDirection.Y - linePoint.Z*lineDirection.Y - lineDirection.Z*_point.Y +
lineDirection.Z*linePoint.Y)/(-_direction.Z*lineDirection.Y + _direction.Y*lineDirection.Z);
}
else
{
throw new Exception("Intersection line not correctly calculated.");
}
NT x = _point.X + _direction.X * t;
NT y = _point.Y + _direction.Y* t;
NT z = _point.Z + _direction.Z * t;
return new Vector3m(x, y, z);
}