开发者

How to find the bisector of an angle in MATLAB

开发者 https://www.devze.com 2023-01-19 23:30 出处:网络
I have a question connected to this code: t = -20:0.1:20; plot3(zeros(size(t)),t,-t.^2); grid on hold on

I have a question connected to this code:

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);
e开发者_如何转开发nd

In this code, I plot two intersecting lines. H1, and H2. H1 is fixed, H2 moves as a function of time. H2 happens to trace a parabola in this example, but its movement could be arbitrary.

How can I calculate and draw the bisector of the angle between these two intersecting lines for every position of the line H2? I would like to see in the plot the bisector and the line H2 moving at the same time.

Solving this problem for one position of H2 is sufficient, since it will be the same procedure for all orientations of H2 relative to H1.


I am not a geometry genius, there is likely an easier way to do this. As of now, no one has responded though, so this will be something.

You have three points in three space: Let A be the common vertice of the two line segments.
Let B and C be two known points on the two line segments.

Choose an arbitrary distance r where

r <= distance from A to B

r <= distance from A to C

Measure from A along line segment AB a distance of r. This is point RB Measure from A along line segment AC a distance or r. This is point RC

Find the mid point of line segment connecting RB and RC. This is point M

Line segment AM is the angular bisector of angle CAB.


Each of these steps should be relatively easy to accomplish.


Here is basically MatlabDoug's method with some improvement on the determination of the point he calls 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


I just use the following:

  1. Find the normalized vectors AB, and AC, where A is the common point of the segments.
  2. V = (AB + AC) * 0.5 // produces the direction vector that bisects AB and AC.

Normalize V, then do A + V * length to get the line segment of the desired length that starts at the common point.

(Note that this method does not work on 3 points along a line to produce a perpendicular bisector, it will yield a vector with no length in that case)

I have added a C# implementation (in the XZ plane using Unity 3D Vector3 struct) that handles Perpendicular and Reflex bisectors in case someone that knows MATLAB would translate it.

    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;
    }

Also note that the returned bisector is a vector of unit length. Using "center + bisector * length" could be used to place it into worldspace.

0

精彩评论

暂无评论...
验证码 换一张
取 消