我正在
Matlab
开展一个项目,需要找到正方形 [-1,+1]x[-1,+1]
内相交于一点 (xIntersection,yIntersection)
的两条线之间的面积。所以我们的想法是减去两条线并在 [-1, xIntersection] 和 [xIntersection, +1] 之间积分,对结果求和,如果为负,则更改其符号。
有关如何找到两条线的交点的详细信息,请检查此链接。
我正在使用
Matlab's
函数 integral()
,这里是我的代码片段:
xIntersection = ((x_1 * y_2 - y_1 * x_2) * (x_3 - x_4) - (x_1 - x_2) * (x_3 * y_4 - y_3 * x_4) ) / ((x_1 - x_2) * (y_3 - y_4) - (y_1 - y_2) * (x_3 - x_4));
d = @(x) g(x) - f(x);
result = integral(d, -1, xIntersection) - int( d, xIntersection, 1)
if(result < 0),
result = result * -1;
end
请注意,我之前在代码中定义了
g(x)
和 f(x)
但尚未在代码片段中报告它。
问题是我很快意识到这些线可以在正方形的内部或外部相交,而且它们可以在正方形的任何一边相交,并且可能的组合数量会很快增加。
即:
这只是 4 种情况,但考虑到 f(+1)、f(-1)、g(+1)、g(-1) 可能在区间 [-1,+1] 内、高于或低于并且交点可以在正方形内部或外部,总数为 3*3*3*3*2 = 162。
显然,在每种情况下,为了获得两条线之间的面积而进行积分的显式函数是不同的,但我不可能想到为每条线编写一个 switch case。
有什么想法吗?
我认为我对你之前问题的回答在很大程度上仍然适用。
如果你想计算由两条线的较小角度和正方形边界所包围的区域的面积,那么你可以忘记交集,并忘记所有不同的情况。
您可以使用以下事实:
该积分的值
A = quadgk(@(x) ...
abs( max(min(line1(x),+1),-1) - max(min(line2(x),+1),-1) ), -1, +1);
给出线之间的面积(有时是大角度,有时是小角度)
min(A, S-A)
的值是正确答案(始终是小角度)。假设“线之间”是指“线形成的较小角度内”:
以线
l
和h
、S := [-1,+1]x[-1,+1]
和B
作为S
的边界。
使用
l
和 l_1 + t*l_2
蜜蜂向量将 l_1
转换为 l_2
形式。对 h 做同样的事情。
S
内部,则找到l
和h
与B
的4个交点。对它们进行排序,得到一个凸四边形。 计算它的面积。p
并找到 α
和
l_2
之间的交角
h_2
。然后检查:
α
在 [90°,180°]
中或 α
在 [270°,360°]
中,则交换 l
和 h
。α > 180°
,则设置 l_2 = −l_2
l_1 := h_1 := p
。做一次积极的t
和消极的t
(从 l_2
沿着 h_2
和 p
向前和向后):
这种情况仍然不少,但我认为没有办法解决这个问题。您可以通过使用三角形和四边形的多边形公式来稍微简化这一点。
如何对点进行排序以获得凸多边形/四边形:选择其中任意一个作为
p_1
,然后根据角度对其余点进行排序 p_1
。
如果您定义一个
intersection
函数和一个 polygon_area
来获取点列表,对它们进行排序并返回面积,则该算法应该相当容易实现。
编辑:帮助解释评论的图像:
嘿伙计们,谢谢你们的回答,我还想到了一种经验方法来找到线条之间的区域,并为了讨论和完整性而想分享它。
如果您在正方形内取大量随机点
[-1,+1]x[-1,+1]
,您可以将面积测量为落在两条线之间的区域中的点的分数。
这里有一个小片段和两张图像,以显示使用不同数量的点获得的经验结果的不同准确性。
minX = -1;
maxX = +1;
errors = 0;
size = 10000;
for j=1:size,
%random point in [-1,+1]
T(j,:) = minX + (maxX - minX).*rand(2,1);
%equation of the two lines is used to compute the y-value
y1 = ( ( B(2) - A(2) ) / ( B(1) - A(1) ) ) * (T(j,1) - A(1)) + A(2);
y2 = (- W(1) / W(2)) * T(j,1) -tresh / W(2);
if(T(j,2) < y1),
%point is under line one
Y1 = -1;
else
%point is above line one
Y1 = +1;
end
if(T(j,2) < y2),
%point is under line two
Y2 = -1;
else
%point is above line two
Y2 = +1;
end
if(Y1 * Y2 < 0),
errors = errors + 1;
scatter(T(j,1),T(j,2),'fill','r')
else
scatter(T(j,1),T(j,2),'fill','g')
end
end
area = (errors / size) / 4;
这里有两张图片,它肯定比@Rody 发布的解决方案需要更长的时间,但正如您所看到的,您可以使其准确。
点数 = 10000