首页 > 解决方案 > 曲线的旋转、曲线的交点和for循环的应用【浮点比较问题】】

问题描述

问题场景定义如下问题陈述(点击这里)

此链接中提供了一次迭代中发生的信息

我应该让一个小圆弧在两端接触圆(曲线 1 围绕点旋转圆A,然后在点处旋转接触圆,B因此圆弧的两端都接触圆)。当我手动执行此操作时,我得到了结果,我通过使用找到交叉点polyxpoly(),将弧线放在交叉点上并继续旋转它直到它接触圆。但是当我尝试通过使用 for 循环来自动化许多弧的过程时,我没有得到想要的结果。

由于发生了弧的旋转,我给出了小的旋转步长,但我得到了不同的结果。有时 for 循环正常工作并给出所需的结果,有时会在某些迭代中给出异常结果。我无法弄清楚我的方法的问题。

结果如下 点击这里查看结果

这些是额外的详细信息,显示了期望结果和不期望结果之间的差异 theta=500 和 i=2 的期望结果与不期望的结果,3 期望结果与 theta=1800 和 i=4 的不期望结果之间的差异

可以看出,theta = 500 & i = 2圆弧不旋转,并且由于它不旋转,所以它给出了相同的结果,theta = 500 & i = 3 但是当theta = 1800它给出不同的结果但在迭代 4 时失败(fortheta = 1800 i = 1,2,3给出所需的结果但在 时失败i = 4)。检查结果图像。

我使用的代码如下,但 For-loop 会根据 theta 为某些迭代给出异常结果

clc,clear
r = 10;                     % arc length
R = 55;                     % radius of a circle
aa = 60*pi/180;              % arc angle
ap = 0*pi/180;             % arc position angle
k=0;

t = linspace(0,pi/2);
[x,y] = pol2cart(t,R);      % circle data
t1 = linspace(0,aa)-aa/2+ap;
[x1,y1] = pol2cart(t1,r); % arc data
% Intersection of x axis (y=0) and quarter circle
x_axis_range=1:1000;
y_val_on_x_axis=zeros(1,length(x_axis_range));
[x1rc,y1rc]=polyxpoly(x_axis_range,y_val_on_x_axis,x,y);
xc_s(1)=x1rc;
yc_s(1)=y1rc;
% x1rc=55;
% y1rc=0;
for z=1:3
[x1_p,y1_p]= placement(x,y,x1,y1,x1rc,y1rc);
[x1_rotated,y1_rotated,xc,yc]=rotate(x,y,x1_p,y1_p,x1rc,y1rc);
%[x1_rotated,y1_rotated,xc,yc]=rotate(x,y,x1,y1,x1rc,y1rc);
x1rc=xc;
y1rc=yc;
end
% havent written the plot command

Placement()- placement()的目的是将新的圆弧移动到前一个圆弧和圆的交点

function [x1_p,y1_p] = placement(x,y,x1,y1,x1rc,y1rc)

xcen=x1rc;
ycen=y1rc;

% shifting arc-lower-end to (t(1),0) or (
delx=xcen-x1(1); % Finding the x difference between arc-lower-end x-coordinate & x(1)[circle]
dely=ycen-y1(1); % Finding the y difference between arc-lower-end y-coordinate & y(1) [circle]

x1_p=x1+delx;
y1_p=y1+dely;
end

旋转function()

 function [x1_rotated,y1_rotated,xc,yc] = rotate(x,y,x1_p,y1_p,x1rc,y1rc)
    % [x1_p,y1_p]= placement(x,y,x1,y1,x1rc,y1rc);
    theta =linspace(0,pi,500);
    i=1;
    xc=[];
    yc=[];
    xcen=x1rc;
    ycen=y1rc;
    while isempty(xc)||xc==xcen && isempty(yc)||yc==ycen
    % create a matrix of these points, which will be useful in future calculations
    v = [x1_p;y1_p];
    % choose a point which will be the center of rotation
    x_center = xcen;
    y_center = ycen;
    % create a matrix which will be used later in calculations
    center = repmat([x_center; y_center], 1, length(x1_p));
    % define a theta degree counter-clockwise rotation matrix
    R = [cos(theta(i)) -sin(theta(i)); sin(theta(i)) cos(theta(i))];
    % do the rotation...
    s = v - center;     % shift points in the plane so that the center of rotation is at the origin
    so = R*s;           % apply the rotation about the origin
    vo = so + center;   % shift again so the origin goes back to the desired center of rotation
    % this can be done in one line as:
    % vo = R*(v - center) + center
    % pick out the vectors of rotated x- and y-data
    x1_rotated = vo(1,:);
    y1_rotated = vo(2,:);
    [xc,yc] = polyxpoly(x1_rotated,y1_rotated,x,y);
    [xc1,yc1] = polyxpoly(x1_p,y1_p,x,y);
    if length(xc)==2
    xc=xc(2);
    yc=yc(2);
    end
    i=i+1;
    end
    end

我尝试如下修改“if语句”,但似乎在某个迭代之后它不起作用。if语句中新的修改如下

   if length(xc)==2
   ubx=xc(1); lbx=xc(2);
   uby=yc(2);lby=yc(1);
   xc=xc(2);
   yc=yc(2)
    
  ub=[ubx uby];
  lb=[lbx-4 lby];
  end

然后我试图返回 ub 和 lb 并得到以下错误消息 输出参数“ub”(可能还有其他)在调用“旋转”期间未分配。for 循环的第五次迭代之后。if 语句适用于 1,2,3,4 迭代

标签: matlabfor-loopmathgeometryrotation

解决方案


这是一个浮点 比较问题 。长话短说,两者都返回false(避免浮点算术的常见问题)。 3*(4/3 -1) == 1sin(pi)==0

将您的 while 条件更改为如下所示:

while (isempty(xc)||abs(xc-xcen)<=10*eps(xcen)) && (isempty(yc)||abs(yc-ycen)<=10*eps(ycen))

在此处输入图像描述

顺便说一句,您假设polyxpoly返回 2 点时,第二点是您的结果,这是不正确的。尝试找到距离圆弧起点最远的点:

if length(xc)>1
    [~, i] = max((xc-xcen).^2+(yc-ycen).^2);
    xc=xc(i);
    yc=yc(i);
end

推荐阅读