我想对向量进行归一化,但是我不知道如何进行这样一个基本操作。不存在像Vector_3::normalize()这样的直接方法。我调用squared_length()然后调用CGAL::sqr_root()来求向量的长度,然后当我想把向量除以它的长度时,编译器不允许,因为CGAL类型不兼容,我哪里错了?
vyswwuz21#
我在这里扩展了@MarcGlisse的评论。有两种情况--你想精确计算或不想精确计算。在第一种情况下,你可以使用Exact_predicates_exact_constructions_kernel_with_sqrt,归一化向量将是精确的。在第二种情况下,你可以使用许多核函数,但是归一化向量的长度可能与1略有不同。另外,有些核函数根本没有CGAL::sqrt函数--但是你总是可以使用CGAL::to_double函数将平方距离转换为double类型。另一种方法是使用CGAL::approximate_sqrt函数。它会在必要时自动执行此转换。这些转换会使计算不精确。请参见下面的示例:
Exact_predicates_exact_constructions_kernel_with_sqrt
1
CGAL::sqrt
CGAL::to_double
double
CGAL::approximate_sqrt
#include <iostream> #include <CGAL/Exact_predicates_exact_constructions_kernel_with_sqrt.h> #include <CGAL/Exact_predicates_exact_constructions_kernel.h> #include <CGAL/Simple_cartesian.h> using KernelExactWithSqrt = CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt; using KernelExact = CGAL::Exact_predicates_exact_constructions_kernel; using KernelInexact = CGAL::Simple_cartesian<double>; template <typename T> auto normalize(T const& V) { auto const slen = V.squared_length(); auto const d = CGAL::approximate_sqrt(slen); return V / d; } template <typename T> auto check() { typename T::Point_2 const p{0, 0}, q{1, 1}; auto const n = normalize(typename T::Vector_2{p, q}); return n.squared_length() == 1; } int main() { std::cout << "====== Exact kernel with square root ======" << std::endl; std::cout << check<KernelExactWithSqrt>() << std::endl; std::cout << "====== Inexact kernel ======" << std::endl; std::cout << check<KernelInexact>() << std::endl; std::cout << "====== Exact kernel with automatic conversion to double ======" << std::endl; std::cout << check<KernelExact>() << std::endl; }
输出:
====== Exact kernel with square root ====== 1 ====== Inexact kernel ====== 0 ====== Exact kernel with automatic conversion to double ====== 0
因此,这个例子说明了Exact_predicates_exact_constructions_kernel_with_sqrt保证了归一化向量将是您所期望的。
1条答案
按热度按时间vyswwuz21#
我在这里扩展了@MarcGlisse的评论。
有两种情况--你想精确计算或不想精确计算。在第一种情况下,你可以使用
Exact_predicates_exact_constructions_kernel_with_sqrt
,归一化向量将是精确的。在第二种情况下,你可以使用许多核函数,但是归一化向量的长度可能与
1
略有不同。另外,有些核函数根本没有CGAL::sqrt
函数--但是你总是可以使用CGAL::to_double
函数将平方距离转换为double
类型。另一种方法是使用CGAL::approximate_sqrt
函数。它会在必要时自动执行此转换。这些转换会使计算不精确。请参见下面的示例:输出:
因此,这个例子说明了
Exact_predicates_exact_constructions_kernel_with_sqrt
保证了归一化向量将是您所期望的。