gpt4 book ai didi

c++ - 避免样条挤压中的扭曲伪影?

转载 作者:搜寻专家 更新时间:2023-10-31 01:36:00 24 4
gpt4 key购买 nike

我正在尝试将 2d 形状轮廓附加到样条曲线。如图所示,在样条曲线的某些点上,我的几何图形中出现了奇怪的扭曲伪影。如何使用 Frenet-Frame 方程避免这种情况?

我目前对法线、副法线和切线的计算:

forward_tangent_vector = glm::normalize(pointforward - pointmid);
backward_tangent_vector = glm::normalize(pointmid - pointback);
second_order_tangent = glm::normalize(forward_tangent_vector - backward_tangent_vector);
binormal = glm::normalize(glm::cross(forward_tangent_vector,second_order_tangent));
normal = glm::normalize(glm::cross(binormal, forward_tangent_vector));

//translation matrix
T = glm::translate(T, pointmid);

normal_axis = glm::vec3(0, 1, 0);
rotationAxis = glm::cross(normal_axis, forward_tangent_vector);
rotationAngle = glm::acos(glm::dot(normal_axis, forward_tangent_vector));

//rotation matrix
R = glm::rotate(R, glm::degrees(rotationAngle), rotationAxis);

enter image description here

最佳答案

您成为 hairy ball theorem 的受害者:

A common problem in computer graphics is to generate a non-zero vector in R3 that is orthogonal to a given non-zero one. There is no single continuous function that can do this for all non-zero vector inputs. This is a corollary of the hairy ball theorem. To see this, consider the given vector as the radius of a sphere and note that finding a non-zero vector orthogonal to the given one is equivalent to finding a non-zero vector that is tangent to the surface of that sphere where it touches the radius. However, the hairy ball theorem says there exists no continuous function that can do this for every point on the sphere (i.e. every given vector).

另见:http://blog.sigfpe.com/2006/10/oriented-fish-and-hairy-balls.html

问题出在这两行:

normal_axis = glm::vec3(0, 1, 0);
rotationAxis = glm::cross(normal_axis, forward_tangent_vector);

forward_tangent_vector(0,1,0)共线时,rotationAxis变为(0,0,0)。这就是为什么你的管道会震动。

您需要做的不是硬编码(0,1,0),而是取样条曲线的一阶导数(速度/切线 vector ),取样条曲线的二阶导数(加速度/法 vector ),并取它们的叉积(二法 vector )。对这三个 vector 进行归一化,得到所谓的 Frenet-frame。 ,围绕样条的一组 3 个相互垂直的 vector 。

请注意,您的样条曲线必须是 C2 连续的,否则您会得到类似的由二阶导数(也称为加速度/法 vector )的不连续性引起的“扭曲”。

一旦有了 Frenet 坐标系,只需简单更改基础即可在该坐标系中工作。不要乱用 glm::rotate,只需将 x、y、z 单位 vector 作为行(或列)放入矩阵中?我不确定 GLM 使用什么约定...)这就是您的转换矩阵。

关于c++ - 避免样条挤压中的扭曲伪影?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36376022/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com