Как найти биссектрису угла в MATLAB
У меня есть вопрос, связанный с этим кодом:
t = -20:0.1:20;
plot3(zeros(size(t)),t,-t.^2);
grid on
hold on
i = 1;
h = plot3([0 0],[0 t(i)],[0 -t(i)^2],'r');
h1 = plot3([-1 0],[0 0],[-400 -200],'g');
for(i=2:length(t))
set(h,'xdata',[-1 0],'ydata',[0 t(i)],'zdata',[-400 -t(i)^2]);
pause(0.01);
end
В этом коде я рисую две пересекающиеся линии. H1 и H2. H1 фиксирован, H2 движется как функция времени. В этом примере H2 обнаруживает параболу, но ее движение может быть произвольным.
Как я могу рассчитать и нарисовать биссектрису угла между этими двумя пересекающимися линиями для каждой позиции линии H2? Я хотел бы видеть на графике биссектрису и линию H2, движущиеся одновременно.
Решение этой проблемы для одной позиции H2 достаточно, так как она будет одинаковой для всех ориентаций H2 относительно H1.
2 ответа
Вот в основном метод MatlabDoug с некоторым улучшением определения точки, которую он называет M.
t = -20:0.1:20;
plot3(zeros(size(t)),t,-t.^2);
grid on
hold on
v1 = [1 0 200];
v1 = v1/norm(v1);
i = 1;
h = plot3([-1 0],[0 t(i)],[-400 -t(i)^2],'r');
h1 = plot3([-1 0],[0 0],[-400 -200],'g');
l = norm([1 t(i) -t(i)^2+400]);
p = l*v1 + [-1 0 -400];
v2 = (p + [0 t(i) -t(i)^2])/2 - [-1 0 -400];
p2 = [-1 0 -400] + v2/v2(1);
h2 = plot3([-1 p2(1)],[0 p2(2)],[-400 p2(3)],'m');
pause(0.1)
for(i=2:length(t))
l = norm([1 t(i) -t(i)^2+400]);
p = l*v1 + [-1 0 -400];
v2 = (p + [0 t(i) -t(i)^2])/2 - [-1 0 -400];
p2 = [-1 0 -400] + v2/v2(1);
set(h,'xdata',[-1 0],'ydata',[0 t(i)],'zdata',[-400 -t(i)^2]);
set(h2,'xdata',[-1 p2(1)],'ydata',[0 p2(2)],'zdata',[-400 p2(3)]);
pause;
end
Я не гений геометрии, вероятно, есть более простой способ сделать это. Пока никто не ответил, так что это будет что-то.
У вас есть три точки в трех пространствах: Пусть A - общая вершина двух отрезков.
Пусть B и C - две известные точки на двух отрезках.
Выберите произвольное расстояние r где
r <= расстояние от A до B
r <= расстояние от А до С
Измерьте от A вдоль отрезка AB расстояние r. Это точка RB Measure от A вдоль отрезка AC расстояние или r. Это точка RC
Найдите среднюю точку отрезка, соединяющего RB и RC. Это точка М
Сегмент AM - это угловой биссектриса угла CAB.
Каждый из этих шагов должен быть относительно простым для выполнения.
Я просто использую следующее:
- Найдите нормированные векторы AB и AC, где A - точка пересечения отрезков.
- V = (AB + AC) * 0.5 // создает вектор направления, который делит пополам AB и AC.
Нормализовать V, затем выполнить A + V * length, чтобы получить отрезок нужной длины, который начинается в общей точке.
(Обратите внимание, что этот метод не работает с 3 точками вдоль линии для получения серединного перпендикуляра, в этом случае он даст вектор без длины)
Я добавил реализацию C# (в плоскости XZ с использованием структуры Unity 3D Vector3), которая обрабатывает биссектрисы Perpendicular и Reflex на случай, если кто-то, кто знает MATLAB, переведет ее.
public Vector3 GetBisector(Vector3 center, Vector3 first, Vector3 second)
{
Vector3 firstDir = (first - center).normalized;
Vector3 secondDir = (second - center).normalized;
Vector3 result = ((firstDir + secondDir) * 0.5f).normalized;
if (IsGreaterThan180(-firstDir, secondDir))
{
// make into a reflex vector
(result.x, result.z) = (-result.x, -result.z);
}
if (result.sqrMagnitude < 0.99f)
{
// we have a colinear set of lines.
// return the perpendicular bisector.
result = Vector3.Cross(Vector3.up, -firstDir).normalized;
}
return result;
}
bool IsGreaterThan180(Vector3 dir, Vector3 dir2)
{
// < 0.0 for clockwise ordering
return (dir2.x * dir.z - dir2.z * dir.x) < 0.0f;
}
Также обратите внимание, что возвращенная биссектриса - это вектор единичной длины. Использование "центр + биссектриса * длина" может быть использовано для размещения его в мировом пространстве.