绕单位圆旋转直线到任意位置

Rotate line to arbitary position around unit circle

我有一个单位圆,标有 n 个单位根。我希望能够旋转、平移和缩放位于 x 轴(-1 和 1 之间)上的一条线,以连接任何一对标记的根。目前我的代码在某些情况下可以做到这一点,但一般情况下不起作用。我想避免硬编码每对可能的线应该如何移动。这是我目前所拥有的:

clear

%% Roots of unity
n = 10;
roots = zeros(1, n);
for k = 1 : n
    roots(k) = exp(2 * k* pi * 1i / n);
end

%% Move line
% Pair of roots the line should connect
point_1 = roots(2);
point_2 = roots(6);

% Coordinates of pair of roots
x1 = real(point_1);
x2 = real(point_2);
y1 = imag(point_1);
y2 = imag(point_2);

d = sqrt((x1-x2)^2+(y1-y2)^2); % Euclidean distance between pair of roots
m = (y1 - y2) / (x1 - x2); % Gradient of line connecting pair of roots
c = y1 - m * x1; % y-intercept of line

int = -c / m; % x-coordinate that the rotation should occur at
shift = [int; 0];

x = linspace(-1, 1, 10); % Initial line lying purely on x-axis
y = 0 * x;
v = [x; y];

theta = atan((y2-shift(2))/(x2-shift(1))); % Angle by which to rotate

rot = [cos(theta), -sin(theta); sin(theta), cos(theta)]; % Rotation matrix

u = v * (d / 2); % Scale initial line

if m < 1e-3  % Horizontal case
    shift = [0; 0];
end

w = (rot * (u - shift)) + shift; % Apply rotation

% Another shift that seems necessary
% This is definitely a problematic section
shift_x = w(1, 1) - x2;
shift_y = w(2, 1) - y2;
shift_2 = [shift_x; shift_y];
w = w - shift_2;


%% Plot
fig = figure;
fig.Units = 'inches';
fig.Position = [1, 1, 9, 9];
ax = gca;
tt = title(ax, 'Title');
tt.FontWeight = 'bold';
tt.FontSize = 20;
st = subtitle(ax, sprintf('More text here'));
st.FontAngle = 'italic';
st.FontSize = 15;

hold on
hCircle = viscircles([0, 0], 1, 'Color', 'k');
for i = 1 : n
   x_point = real(roots(i));
   y_point = imag(roots(i));
   hPin = plot(x_point, y_point, 'Marker', 'o', 'MarkerSize', 20, 'MarkerfaceColor', 'red', ...
       'MarkerEdgeColor', 'black');
end

% Plot original and shifted line, split into colours so direction is easier to see
plot(v(1,1:4), v(2,1:4), 'b');
plot(v(1,4:7), v(2,4:7), 'r');
plot(v(1,7:end), v(2,7:end), 'g');

plot(w(1,1:4), w(2,1:4), 'b');
plot(w(1,4:7), w(2,4:7), 'r');
plot(w(1,7:end), w(2,7:end), 'g');

例如,保留 point_1 = roots(2); 并仅更改 point_2 = roots(p); 仅适用于 p=3, 4, 6, 7, 8。

如能提供有关如何实现此功能的指导,我们将不胜感激,谢谢!

编辑: 为了提供更多细节,基本上我有一个介于 0 和 1 之间的数字数组(而不仅仅是一条线),我想将其绘制在连接两个根的线上。例如。如果我的数组是 x=[0.2, 0.5, 0.9],那么我想要 point_1point_2 之间的三个点,第一个是远离 point_1 的连接线下方 0.2d,第二个 0.5d(即中途),最后一个距离为 0.9d。

首先,由于要连接的点是复数,所以直接用复坐标比较容易。

团结的根源
我稍微简化了您的代码。
有些人可能会在命名变量 roots 时举起旗帜,因为 roots 是一个 built-in matlab 函数。我很好,只要使用不会引起任何混淆,即不要在同一上下文中将 roots 用作变量和函数。
由于 matlab 提供了如此多的 built-in 函数,因此不可能避免名称冲突,除非人们将它们全部记住或在命名每个变量之前进行搜索。

n = 10;
k = 1:n;
roots = exp(2 * k * pi * 1i / n);

缩放、旋转和平移

% Pair of roots the line should connect
point_1 = roots(2);
point_2 = roots(6);

d = abs(point_2 - point_1);         % distance between pair of roots
theta = angle(point_2 - point_1);   % rotation angle

p_on_line = linspace(-1, 1, 10);                    % Initial line lying on x-axis
p_on_line = p_on_line * d/2;                        % scale
p_on_line = p_on_line * exp(1i*theta);              % rotate
p_on_line = p_on_line + (point_1 - p_on_line(1));   % translate

情节
我添加了一些散点并删除了不相关的部分(例如标题,字体)。

fig = figure;
fig.Units = 'inches';
fig.Position = [1, 1, 9, 9];

hold on
hCircle = viscircles([0, 0], 1, 'Color', 'k');
hPin = plot(roots, 'o', 'MarkerSize', 20, 'MarkerfaceColor', 'red', ...
            'MarkerEdgeColor', 'black');

% Plot line connecting roots
plot(p_on_line(1:4), 'b.-', 'MarkerSize', 20);
plot(p_on_line(4:7), 'r.-', 'MarkerSize', 20);
plot(p_on_line(7:end), 'g.-', 'MarkerSize', 20);

% Plot original line
original_x = linspace(-1, 1, 10);
original_y = zeros(1, 10);
plot(original_x(1:4), original_y(1:4), 'b.-', 'MarkerSize', 20);
plot(original_x(4:7), original_y(4:7), 'r.-', 'MarkerSize', 20);
plot(original_x(7:end), original_y(7:end), 'g.-', 'MarkerSize', 20);
hold off

这应该适用于所有根对组合。