繁体   English   中英

曲线的旋转、曲线的交点和for循环的应用【浮点比较问题】】

[英]Rotation of curves , intersection of curve and for -loop application [Floating point comparison problem]]

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

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

我应该让一个小圆弧在两端接触圆(曲线 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 时失败(对于theta = 1800 i = 1,2,3给出了预期的结果,但在i = 4处失败)。 检查结果图像。

  • 参数theta可以在rotation()中找到

我使用的代码如下,但 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 并收到以下错误消息Output 参数“ub”(可能还有其他)在调用“旋转”期间未分配。 for 循环第五次迭代之后。 if 语句适用于 1,2,3,4 迭代

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

将您的 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM