如何在平面中从3分(x,y,z)创建一个弧路径?

发布于 2025-01-29 12:42:47 字数 153 浏览 3 评论 0 原文

我想在n = 3点p(n)=(x,y,z)上创建一个弧形轨迹交叉,我决定在平面上绘制一个圆圈。因此,我有中心,半径,theta(x,y平面的角度)和phi(Z轴围绕Z轴),我知道3点(x,y,z)的位置,我如何在P1之间提取弧度来自这个圆的P2和P3?我在Matlab中实施了此程序。 多谢。

I want to create an arc trajectory cross over n=3 points P(n)=(x, y, z), I decided to draw a circle over 3 points in plane. so I have center, radius, theta (angle in x, y plane) and phi(angle around z axis), and I know the position of 3 points (x, y, z), How can I extract an arc between p1 , p2 and p3 from this circle? I implemented this program in MATLAB..
Thanks a lot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

久光 2025-02-05 12:42:47

此答案在Math.stackexchange上提供了一个很好的简单配方,以查找圆圈中心(以及半径)

在其他有用的Math.stackexchange答案中,我们可以根据中心和两个(非尺度)点从原始3。

3D给定中心的圆的参数方程,在圆圈中有两个点? (@milbrandt)

最后,我们需要3个点的3个角度来定义ARC,可以使用 atan2 以及在其他步骤中创建的组件向量进行。

完整注释的代码在下面,该代码产生该图,并且功能可以计算任何3D点的圆角,然后在任何角度的圆周上的值。

% Original points
p1 = [1;0;2];
p2 = [0;0;0];
p3 = [1;2;2];
P = [p1,p2,p3];

% Get circle definition and 3D planar normal to it
p0 = getCentre(p1,p2,p3);
r = norm( p0 - p1 );
[n0,idx] = getNormal(p0,p1,p2,p3);
% Vectors to describe the plane
q1 = P(:,idx(1));
q2 = p0 + cross(n0,(p1-p0).').';
% Function to compute circle point at given angle
fc = @(a) p0 + cos(a).*(q1-p0) + sin(a).*(q2-p0);
% Get angles of the original points for the circle formula
a1 = angleFromPoint(p0,p1,q1,q2);
a2 = angleFromPoint(p0,p2,q1,q2);
a3 = angleFromPoint(p0,p3,q1,q2);
% Plot
figure(1); clf; hold on;
args = {'markersize',20,'displayname'};
plot3( P(1,:), P(2,:), P(3,:), '.', args{:}, 'Original Points' ); 
plot3( p0(1), p0(2), p0(3), '.k', args{:}, 'Centre' );   
plotArc(fc,a1,a2); % plot arc from p1 to p2
plotArc(fc,a2,a3); % plot arc from p2 to p3
plotArc(fc,a3,a1); % plot arc from p3 to p1
grid on; legend show; view(-50,40);

function ang = angleFromPoint(p0,p,q1,q2)
    % Get the circle angle for point 'p'
    comp = @(a,b) dot(a,b)/norm(b);
    ang = atan2( comp(p-p0,q2-p0), comp(p-p0,q1-p0) );
end
function plotArc(fc,a,b)
    % Plot circle arc between angles 'a' and 'b' for circle function 'fc'
    while a > b
        a = a - 2*pi; % ensure we always go from a to b
    end
    aa = linspace( a, b, 100 );
    c = fc(aa);
    plot3( c(1,:), c(2,:), c(3,:), '.r', 'markersize', 5, 'handlevisibility', 'off' );
end
function p0 = getCentre(p1,p2,p3)
    % Get centre of circle defined by 3D points 'p1','p2','p3'
    v1 = p2 - p1;
    v2 = p3 - p1;

    v11 = dot( v1.', v1 );
    v22 = dot( v2.', v2 );
    v12 = dot( v1.', v2 );

    b = 1/(2*(v11*v22-v12^2));
    k1 = b * v22 * (v11-v12);
    k2 = b * v11 * (v22-v12);

    p0 = p1 + k1*v1 + k2*v2;
end
function [n0,idx] = getNormal(p0,p1,p2,p3)
    % compute all 3 normals in case two points are colinear with centre
    n12 = cross((p1 - p0),(p2 - p0));
    n23 = cross((p3 - p0),(p2 - p0));
    n13 = cross((p3 - p0),(p1 - p0));

    n = [n12,n23,n13];
    n = n./sign(n(1,:));
    idx = find(~all(isnan(n)),2);
    n = n(:,idx(1));
    n0 = n / norm(n);
end

This answer on math.stackexchange gives a nice simple formulation for finding the circle centre (and therefore the radius)

3D coordinates of circle center given three point on the circle. (@Sergio G.)

From this other helpful math.stackexchange answer we can define any point on that circle in terms of the centre and two (non-colinear) points from the original 3.

Parametric equation of a circle in 3D given center and two points on the circle? (@milbrandt)

Finally we need the 3 angles of your 3 points to define the arcs, which can be done with atan2 and the component vectors created in the other steps.

The full commented code is below, which yields this plot, and functions to compute the circle angle for any 3D point, then the value on the circumference for any angle.

circle plot 3D

% Original points
p1 = [1;0;2];
p2 = [0;0;0];
p3 = [1;2;2];
P = [p1,p2,p3];

% Get circle definition and 3D planar normal to it
p0 = getCentre(p1,p2,p3);
r = norm( p0 - p1 );
[n0,idx] = getNormal(p0,p1,p2,p3);
% Vectors to describe the plane
q1 = P(:,idx(1));
q2 = p0 + cross(n0,(p1-p0).').';
% Function to compute circle point at given angle
fc = @(a) p0 + cos(a).*(q1-p0) + sin(a).*(q2-p0);
% Get angles of the original points for the circle formula
a1 = angleFromPoint(p0,p1,q1,q2);
a2 = angleFromPoint(p0,p2,q1,q2);
a3 = angleFromPoint(p0,p3,q1,q2);
% Plot
figure(1); clf; hold on;
args = {'markersize',20,'displayname'};
plot3( P(1,:), P(2,:), P(3,:), '.', args{:}, 'Original Points' ); 
plot3( p0(1), p0(2), p0(3), '.k', args{:}, 'Centre' );   
plotArc(fc,a1,a2); % plot arc from p1 to p2
plotArc(fc,a2,a3); % plot arc from p2 to p3
plotArc(fc,a3,a1); % plot arc from p3 to p1
grid on; legend show; view(-50,40);

function ang = angleFromPoint(p0,p,q1,q2)
    % Get the circle angle for point 'p'
    comp = @(a,b) dot(a,b)/norm(b);
    ang = atan2( comp(p-p0,q2-p0), comp(p-p0,q1-p0) );
end
function plotArc(fc,a,b)
    % Plot circle arc between angles 'a' and 'b' for circle function 'fc'
    while a > b
        a = a - 2*pi; % ensure we always go from a to b
    end
    aa = linspace( a, b, 100 );
    c = fc(aa);
    plot3( c(1,:), c(2,:), c(3,:), '.r', 'markersize', 5, 'handlevisibility', 'off' );
end
function p0 = getCentre(p1,p2,p3)
    % Get centre of circle defined by 3D points 'p1','p2','p3'
    v1 = p2 - p1;
    v2 = p3 - p1;

    v11 = dot( v1.', v1 );
    v22 = dot( v2.', v2 );
    v12 = dot( v1.', v2 );

    b = 1/(2*(v11*v22-v12^2));
    k1 = b * v22 * (v11-v12);
    k2 = b * v11 * (v22-v12);

    p0 = p1 + k1*v1 + k2*v2;
end
function [n0,idx] = getNormal(p0,p1,p2,p3)
    % compute all 3 normals in case two points are colinear with centre
    n12 = cross((p1 - p0),(p2 - p0));
    n23 = cross((p3 - p0),(p2 - p0));
    n13 = cross((p3 - p0),(p1 - p0));

    n = [n12,n23,n13];
    n = n./sign(n(1,:));
    idx = find(~all(isnan(n)),2);
    n = n(:,idx(1));
    n0 = n / norm(n);
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文