圆与三角形相交问题,设计算法代码

给出三角形三个顶点
三条边有一条始终在圆外
圆形的半径,圆的圆心

求出相交面积
有多种情况代码解析
用MATLAB


%%
% 给出三角形三个顶点
% 三条边有一条始终在圆外
% 圆形的半径,圆的圆心
% 
% 求出相交面积
% 有多种情况代码解析
% 用MATLAB
%%
%按照圆心到三条边长a,b,c与圆半径R的关系,可以分成(相切也算在圆外)
%一,a,b,c全小于等于半径R,重合为圆的面积,不符合要求
%二,a,b,c有两条边到圆心距离小于等于R,另一条大于R,符合
%三,a,b,c有一条边到圆心距离小于等于R,另两条大于R,符合
%四,a,b,c全大于R,不符合要求
%%


%圆
rx=3;ry=6;R=1; %(3,6) R=1

%两条在外
A=[1,7;3,8;8,1]; %(1,7)  (3,8)  (8,1)
%画图
figure;
huatu(A,rx,ry,R);
title('两条在外');
%判断
YuanSanJiao(1,3,6,A(1,1),A(1,2),A(2,1),A(2,2),A(3,1),A(3,2));

%都在外
A=[0.5,4;3,8;8,1]; 
%画图
figure;
huatu(A,rx,ry,R);
title('都在外');
%判断
YuanSanJiao(1,3,6,A(1,1),A(1,2),A(2,1),A(2,2),A(3,1),A(3,2));


%一条在外
A=[1,7;3,8;6,1]; 
%画图
figure;
huatu(A,rx,ry,R);
title('一条在外');
%判断
YuanSanJiao(1,3,6,A(1,1),A(1,2),A(2,1),A(2,2),A(3,1),A(3,2));

%都在内
A=[2.5,6;3.5,6;6,1];
%画图
figure;
huatu(A,rx,ry,R);
title('都在内');
%判断
YuanSanJiao(1,3,6,A(1,1),A(1,2),A(2,1),A(2,2),A(3,1),A(3,2));


YuanSanJiao.m

function [ Area,Situa ] = YuanSanJiao(R,rx,ry, ax,ay,bx,by,cx,cy )

%三个点两两到圆心的距离
L_ab=Dian_dao_juli(ax,ay,bx,by,rx,ry);
L_bc=Dian_dao_juli(bx,by,cx,cy,rx,ry);
L_ac=Dian_dao_juli(ax,ay,cx,cy,rx,ry);

%大于R的个数
iCOunt = 0;
abOut=0;
bcOut=0;
acOut=0;
Area=0;
if(L_ab>R)
    iCOunt = iCOunt+1;
    abOut=1;
end
if(L_bc>R)
    iCOunt = iCOunt+1;
    bcOut=1;
end
if(L_ac>R)
    iCOunt = iCOunt+1;
    acOut=1;
end

switch(iCOunt)
    case 0
        Situa ='所有边在内';
    case 1
        Situa ='一个边在外';
    case 2
        Situa ='两个边在外';
    case 3
        Situa ='三个边在外';
end

disp(Situa);

%重合面积计算
%都在外
if(abOut==1 & bcOut==1 &acOut==1)
    Area = pi*R*R;
end

%一个在外
if(abOut+bcOut+acOut==1)
    %计算弓形面积
    Gong_Gao1=0;
    Gong_Gao2=0;
    if(abOut==1)
        Gong_Gao1=L_bc;
        Gong_Gao2=L_ac;
        else if(bcOut==1)
        Gong_Gao1=L_ab;
        Gong_Gao2=L_ac;
            else if(acOut==1)
        Gong_Gao1=L_bc;
        Gong_Gao2=L_ab;
            end
        end
    end
    gongArea1=GongXingArea(Gong_Gao1,R);
    gongArea2=GongXingArea(Gong_Gao2,R);
    Area = pi*R*R;
    Area = Area-gongArea1-gongArea2;
end


%两个在外
if(abOut+bcOut+acOut==2)
    %计算弓形面积
    Gong_Gao=0;
    if(abOut==0)
        Gong_Gao=L_ab;
        else if(bcOut==0)
        Gong_Gao=L_bc;
            else if(acOut==0)
            Gong_Gao=L_ac;
            end
        end
    end
    gongArea=GongXingArea(Gong_Gao,R);
    Area = pi*R*R;
    Area = Area-gongArea;
end
%都在内
%太难了,不符合就不算了
if(abOut+bcOut+acOut==0)
    Area = nan;
end

disp(['重合面积是',num2str(Area)]);
end

Dian_dao_juli.m


function [ L ] = Dian_dao_juli( p1_x,p1_y, p2_x,p2_y,center_x,center_y)
%y=kx+b;
k=(p2_y-p1_y)/(p2_x-p1_x);
b=p1_y-k*p1_x;
%y=(p2_y-p1_y)/(p2_x-p1_x) * x +p1_y-(p2_y-p1_y)/(p2_x-p1_x)*p1_x;
% (p2_y-p1_y)/(p2_x-p1_x) * x - y + p1_y-(p2_y-p1_y)/(p2_x-p1_x)*p1_x=0;
% kx-y+b=0;
L=abs(k*center_x-1*center_y+b)/sqrt(k*k+1);
end

huatu.m

function huatu( A,rx,ry,R )
plot(A(:,1),A(:,2),'o');
text(A(1,1),A(1,2),'a点');
text(A(2,1),A(2,2),'b点');
text(A(3,1),A(3,2),'c点');
hold on;
plot(rx,ry,'.','markersize',6);
hold on;
line([A(1,1),A(2,1)],[A(1,2),A(2,2)]);
line([A(2,1),A(3,1)],[A(2,2),A(3,2)]);
line([A(3,1),A(1,1)],[A(3,2),A(1,2)]);
hold on;
viscircles([rx ry],R,'Color','r');
axis([min(A(:,1))-2,max(A(:,1))+2 ,min(A(:,2))-2,max(A(:,2))+2]);


end

GongXingArea.m

%计算弓形面积
function [ gongArea ] = GongXingArea( Gong_Gao ,R)
    Area = pi*R*R;
    theta = acos(Gong_Gao/R);
    %扇形
    shanArea = theta/pi * Area;
    %弓形三角
    Gong_Di = 2*sin(theta)*R;
    sanjiaoArea=0.5*Gong_Gao*Gong_Di;
    %弓形
    gongArea = shanArea-sanjiaoArea;

end

img

img

img

img

这个情况有些多的,能对圆的约束条件描述的更清楚些吗,内接圆和任意一个有一条边长在圆内的相交面积?

可以参考这篇文章,python代码:Python矩形和圆的关系,矩形和多边形的关系,https://blog.csdn.net/qq_15028721/article/details/126975704

参考下面链接里提供的思路和代码,讲得很详细。
https://stackoverflow.com/questions/540014/compute-the-area-of-intersection-between-a-circle-and-a-triangle