При постройке нормали с углом больше 90 градусов нормаль строится в противоположную сторону
Дано отрезок (или сегмент Полилинии) в 3D пространстве. Требутеся построить нормаль к выбранному отрезку с определенным углом наклона, заданным пользователем в градусах.
Если угол наклона указано от 0 до 90 включительно, то угол поворота корректен, НО, если угол указан больше 90, то тогда угол поворота идет в обратную сторону. Например, если ввести значение 100 градусов, то угол наклона станет 80 градусов; если указать 120 градусов, то тогда 60 градусов.
Также, нормаль с любым углом должна строиться по часовой стрелке.
Буду очень признателен, если Вы мне объясните мат. часть в этой проблеме..
P.S. Глобальная переменная Angle уже переведена в радианы.
if (Angle != 0)
{
Double cos = Math.Cos(Angle);
Double sin = Math.Sin(Angle);
Double tan = Math.Tan(Angle);
Vertex VA = new Vertex(0, 0, 1);
Vertex axisN = GetULikeMatrix().TransformNormal(VA).Normalize();
Vertex initialPoint = MV.Inverse().Transform(Point1);
Vertex targetPoint = MV.Inverse().Transform(V);
Double edgeLength = new Edge(initialPoint, targetPoint).Length();
Double height = edgeLength * Math.Abs(tan);
// Задается угол поворота с помощью тангенса.
V = targetPoint + axisN * height;
if (Math.Round(cos, 3) == 0)
{
if (sin > 0) V = initialPoint + axisN * edgeLength;
if (sin < 0) V = initialPoint - axisN * edgeLength;
}
// Задается необходимая длина.
V = initialPoint + (V - initialPoint).Normalize() * edgeLength;
V = MV.Transform(V);
}
Ответы (1 шт):
Не могу понять, что вокруг чего вы крутите, в коде куча необъявленных идентификаторов. Я недавно решал кое-что подобное, здесь функция на Python, которая находит вектор, перпендикулярный вектору a
, повёрнутый на угол alpha
в радианах. Если вектор a
не совпадает с вектором z
, то за начало отсчёта (нулевой угол) берётся направление "вверх". В остальных случаях берётся какая-то из других координатных осей.
def _calc_view_up(x_a, y_a, z_a, alpha=0):
"""
Функция рассчитывает вектор c, перпендикулярный вектору a, такой, что
его проекция на положительное направление оси Z максимально,
то есть это вектор, направленный "вверх".
Если вектор a совпадает с осью Z, то значение вектора c
принимается равным [1, 0, 0] (ось X).
Затем рассчитывает вектор b, который получается поворотом вектора c
вокруг вектора a. Возвращает вектор b.
PAREMETERS
----------
x_a, y_a, z_a: float
Вектор a, вокруг которого нужно выполнить поворот
alpha: float
Угол поворота в радианах
"""
a = np.array([x_a, y_a, z_a])
if x_a==y_a==z_a==0:
return np.array([0, 0, 1])
elif z_a == 0:
c = np.array([0, 0, 1])
elif x_a==0 and y_a == 0:
c = np.array([1, 0, 0])
else:
mag = np.sqrt(np.sum(a**2))
x_c1 = ((x_a*z_a)/(math.sqrt(y_a**2+x_a**2)*mag))
x_c2 = -x_c1
y_c1 = ((y_a*z_a)/(math.sqrt(y_a**2+x_a**2)*mag))
y_c2 = -y_c1
z_c1 = -(y_a*y_c1+x_a*x_c1)/z_a
z_c2 = -z_c1
if z_c1 > 0:
c = np.array([x_c1, y_c1, z_c1])
else:
c = np.array([x_c2, y_c2, z_c2])
a = a / np.sqrt(np.sum(a**2))
b = c * np.cos(alpha) + np.cross(a, c) * np.sin(alpha)
return b