CGAL确切数字表现

时间:2016-04-25 09:53:39

标签: c++ computational-geometry cgal

我正在使用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%有效的软件,所以我真的需要精确的计算。 我其实只需要两件事:

  • 3D矢量的精确表示。
  • 确切谓词(关于&lt;,&gt;,==操作)
  • 计算两个三角形之间的交叉线的精确算术。

关于交叉线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);
    }

0 个答案:

没有答案