【并联机构工作空间分析系列1】 多个圆/圆环求交 得到重叠部分边界 Matlab程序

1 两圆求交

1.1 思路

可以将两圆的位置关系分为3种情况:相交相离包含(这里我将外部相切的情况归为相离,内部相切归为包含。)
我们知道两圆的圆心坐标以及半径,就可以根据圆心距与两圆半径距离进行相交情况判断。伪代码如下

%dis为圆心距
if(dis >= r1+r2||abs(r1-r2) >= dis) 
	%相离、包含
    else
    %相交
end

1.2 求交点

首先考虑最一般的情况,及两圆相交,有两个交点。如何求相交点呢?
相交
第一种方法是联立两圆方程求解,这种方法比较暴力,鄙人喜欢温柔一点的。
第二种方式是几何方法:

  1. 求圆心向量AB与X轴夹角θ
  2. 求向量AC与向量AB的夹角α
    联立方程,求出AD
    AD2+ CD2= r12
    DB2+ CD2= r22
    r12+ r22=AB2
    α=acos(AD/AC)

    上述方程没有考虑到∠ACB是否为90°,所以有问题。这里采用余弦定理
    α=acos((r12+AB2-r22)/2*r1*AB)
  3. 那么C点和E点坐标也就知道了。

在这里插入图片描述
具体代码如下

%两圆心连线与X轴夹角,逆时针为正
theta = atan2d(y2-y1,x2-x1);
ad = (r1^2-r2^2+dis^2)/(2*dis);
%交点与圆心1连线的向量与两圆心连线的夹角
alpha = acosd(ad/r1);
crosspoint1 = [x1+r1*cosd(theta+alpha);y1+r1*sind(theta+alpha)];
crosspoint2 = [x1+r1*cosd(theta-alpha);y1+r1*sind(theta-alpha)];
crosspoint = [crosspoint1 crosspoint2];

1.3 选取探测点

找到交点(图中红点)后下一步就是找两圆重合部分,这里以找到重合部分的边界(图中红线)为目标。
相交情况
我们知道一个圆上2个点可以将圆分为2段弧,3个点可以分为3段弧。现在相交圆上有两段弧,我们可以在每段弧中间再取一个点,作为试探点(上图中蓝点),检查该点是否同时满足距离两圆圆心距离小于其圆的半径,若满足则说明该试探点所在的弧为重合部分的边界(即重合弧)。
遍历两圆上的试探点,我们就得到了所有重合弧的信息啦!弧的表示方法有很多种,这里我用5个参数表示一段弧。

x %弧所在圆的坐标
y
r%弧所在圆的半径
startAngle%弧的起始角
plusAngle%弧的增加角

在这里插入图片描述

圆弧的表示

1.4 相离 包含情况

需要注意的是,当两圆为相离或包含关系时是没有交点的,但是怎么确定包含关系时的重合边界呢?
这里可以将整个圆当做一条弧,规定当圆上没有相交点时,人为的增加一个探测点。然后再进行探测点遍历就可以啦
相离情况

相离情况

包含情况

包含情况

2 多圆求交

多个圆相交也是上面的思路,首先对所有圆进行遍历,两两求交点,根据交点求每一个圆上的探测点;再对所有圆进行遍历,检验探测点是否满足条件,满足的话该探测点所在的弧即为重合的边界(重合弧)。
三圆求交

3 圆环求交

3.1 思路

圆如何求交我们已经搞清楚了,两个圆环求交呢?
首先考虑一个圆环是由两个同心圆组成的,一个内圆一个外圆。我们完全可以把一个圆环看成两个圆,从而两个圆环求交的问题就转化成了4个圆求交的问题。

3.2 操作

需要注意的是,探测点与内外圆的判断是不一样的。

  1. 对于外圆,重合部分的探测点到该圆圆心的距离应<=该圆半径
  2. 对于内圆,重合部分的探测点到该圆圆心的距离应>=该圆半径

其他部分都一样
两圆环求交

3 多圆环求交

想必你已经会了
在这里插入图片描述

4 matlab代码

使用了面向对象编程思想,将圆封装成了一个类,包含了圆的位置坐标,半径,交点等属性。
完整程序下载链接: matlab 多圆/圆环求交.

觉得有帮助的话就给我个赞吧!!!

main函数

clear all
% circle = 5*rand(3,4);%随机生成10个圆
%3圆环 前两行为XY坐标,第三行为半径,第四行为内外圆标志
circle = [0,0,4,4,2,2;
    0,0,0,0,3,3;
    1,6,1,6,1,6;
    -1,1,-1,1,-1,1];
%2圆环
% circle = [0,0,5,5;
%     0,0,0,0;
%     3,6,3,6;
%     -1,1,-1,1];
%3外圆
% circle = [-1,1,0;
%           0,0,2;
%          3,3,3;
%           1,1,1];
[~,col] = size(circle);
%-------交点列表 用于画图-------
crossPointsList = [];
%---------弧列表初始化----------
arcList = [];
%---------圆列表初始化----------
cirList(col) = Circle();%建立类对象数组
for i = 1:col
    cirList(i).cirNum = i;
    cirList(i).cirPro = circle(1:3,i) ;
    cirList(i).cirType = circle(4,i) ;
end
%---------遍历所有圆,两两求交--------
for i = 1:col
    for j = i+1:col
        %两圆交点
        crossPoint = ArcIntersection(cirList(i),cirList(j));
        %如果有交点
        if ~isempty(crossPoint)
            %将交点放入交点列表
            crossPointsList(:,end+1:end+2) = crossPoint;
        end
    end
    PlotCir(cirList(i));%画圆
    hold on;
    cirList(i).CrossPointsAngle();
    %画出两交点的中心点
    if ~isempty(cirList(i).middlePoints)
        plot(cirList(i).middlePoints(1,:), ...
            cirList(i).middlePoints(2,:), ...
            'b.','MarkerSize',25);
        hold on;
    end
end
%--------画出交点-----------
if isempty(crossPointsList)
    fprintf('无任何交点\n');
else
    plot(crossPointsList(1,:),crossPointsList(2,:),'r.','MarkerSize',25);
    hold on;
end

%% 判断哪些弧属于重合弧
for i = 1:col
    arcFlag = (1:cirList(i).numArc);
    for j = 1:col
        %跳过自身判断
        if (i == j)
            continue
        end
        pos = cirList(i).middlePoints - cirList(j).cirPro(1:2,:);
        d = (pos(1,:).^2+pos(2,:).^2).^0.5;
        %如果是外圆
        if cirList(j).cirType == 1 
            arcOder_temp = find(d <= cirList(j).cirPro(3)); %满足要求的弧的序号
        else %如果是内圆
            arcOder_temp = find(d >= cirList(j).cirPro(3)); %满足要求的弧的序号
        end
        arcFlag = intersect(arcFlag,arcOder_temp);
    end
    %如果没有n次相交弧
    if isempty(arcFlag)
        fprintf('%d号圆没有n次相交弧\n', cirList(i).cirNum);
        continue;
    else
        arcList_temp = ones(3,size(arcFlag,2)).*cirList(i).cirPro;
        arcList_temp(4,:) = cirList(i).cirArcList(1,arcFlag);
        arcList_temp(5,:) = cirList(i).cirArcList(2,arcFlag);
        arcList = [arcList arcList_temp];
    end
end
%画圆弧
PlotArc(arcList,20)
title('三圆环求交')
xlabel('x')
ylabel('y')
%axis([-5 5 -5 5])

Circle类

classdef Circle < handle
    %圆类
    properties
        %圆的编号
        cirNum
        %圆的属性 x y r
        cirPro
        %圆的类型 1代表外环 -1代表内圆 0代表默认值
        cirType
        %圆的交点列表 交点的 x y
        cirCrossPoints
        %圆弧列表 第一行是弧的起点角度 第二行是弧转过的角度(逆时针)
        cirArcList
        %圆弧数量
        numArc
        %交点中间点 x y angle
        middlePoints
    end
    methods
        
        %构造函数
        function obj = Circle(ciecle,type)
            if nargin == 0
                obj.cirPro = zeros(3,1);
                obj.cirType = 0;
            elseif nargin == 1
                obj.cirPro = ciecle;
                obj.cirType = 0;
            elseif nargin == 2
                obj.cirPro = ciecle;
                obj.cirType = type;
            end
        end
        
        %求交点与圆心连线 与 X轴夹角
        function CrossPointsAngle(obj)
            xr = obj.cirPro(1);
            yr = obj.cirPro(2);
            r = obj.cirPro(3);
            if  ~isempty(obj.cirCrossPoints)
                vector = [obj.cirCrossPoints(1,:)-xr;obj.cirCrossPoints(2,:)-yr];
                %向量与X轴夹角
                angle = atan2d(vector(2,:),vector(1,:));
                %根据夹角排序
                angleOrder = CrossPointsSort(angle);
                %生成圆弧列表
                obj.cirArcList(1,:) = angleOrder;
                obj.cirArcList(2,:) = [diff(angleOrder),angleOrder(1)-angleOrder(end)+360];
                %计算圆弧数量
                obj.numArc = size(obj.cirArcList,2);
                %生成每个段圆弧的中间的探测点
                middleAngle = obj.cirArcList(1,:) + obj.cirArcList(2,:)/2;
                obj.middlePoints = [xr+cosd(middleAngle).*r;yr+sind(middleAngle).*r];
            else %如果一个圆和其他圆没有交点,规定一个默认探测点
                obj.cirArcList(1,:)=0;
                obj.cirArcList(2,:)=360;
                obj.numArc = 1;
                %生成每个段圆弧的中间的探测点
                middleAngle = obj.cirArcList(1,:) + obj.cirArcList(2,:)/2;
                obj.middlePoints = [xr+cosd(middleAngle).*r;yr+sind(middleAngle).*r];
                %fprintf('%d号圆与其他圆均无交点\n',obj.cirNum);
            end
        end
    end
end

%圆的交点排序 交点与X轴夹角从小到大排序
function angleOrder = CrossPointsSort(angle)
array = find(angle<0);
%将小于0°的角度 转为大于0°
angle(array)=angle(array)+360;
%对圆的交点列表进行排序 因为是行排序 用sortrows时需要转置
tempAngle = sortrows(angle',1);
angleOrder = tempAngle';
end
  • 34
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
程序是两相交求交点,输入信息为两心坐标和半径值。如有更好的算法,欢迎交流!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
在这篇参考文献中,作者基于MATLAB 2019b复现了一篇名为《Determination of the Workspace of 6-DOF Parallel Manipulators》的文章内容,并实现了6UPS并联机构的定姿态工作空间求解。具体实施过程可以参考文献中提供的MATLAB代码。 根据文献中的解读,求解并联机构工作空间可以通过求解球体的相交部分来完成。对球体进行切片后,可以将三维空间的球体求交问题转化为二维平面圆环求交问题。这种方法可以得到某一切面的具体函数表达,但计算工作空间体积相对较麻烦。 需要注意的是,为了实现这个过程,本程序使用了MATLAB机器人工具箱中的一些函数,比如transl()和rotz()等。这些函数可以用于坐标变换和旋转操作。 因此,使用MATLAB可以实现并联机构工作空间求解。具体的实施细节可以参考文献中提供的MATLAB代码。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [【并联机构工作空间分析系列2】弧相交法 论文解读及matlab程序](https://blog.csdn.net/qq_42011369/article/details/115000342)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天才小小傲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值