【问题标题】:Area between two lines inside the square [-1,+1] x [-1,+1]正方形内两条线之间的面积 [-1,+1] x [-1,+1]
【发布时间】:2013-09-16 05:14:42
【问题描述】:

我正在Matlab 从事一个项目,需要找到正方形[-1,+1]x[-1,+1] 内两条线之间的区域,它们与点(xIntersection,yIntersection) 相交。所以想法是减去两条线并在[-1,xIntersection]和[xIntersection,+1]之间积分,将结果相加,如果为负,则更改其符号。

有关如何找到两条线的交点的详细信息,请查看link

我正在使用Matlab's 函数integral(),这里是我的代码的sn-p:

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),但没有在sn-p 中报告。

问题是我很快意识到线条可以在正方形的内部或外部相交,而且它们可以在正方形的任何边上相交,并且可能的组合数量增长得非常快。

即:

这只是 4 种情况,但考虑到 f(+1), f(-1), g(+1), g(-1) 可能在区间 [-1,+1] 之内,高于它或在其下方,并且交叉点可能在正方形内部或外部,总数为 3*3*3*3*2 = 162。

显然,在每种情况下,为了获得两条线之间的区域而进行集成的显式函数是不同的,但我不可能想到为每条线编写一个 switch case。

有什么想法吗?

【问题讨论】:

  • 你如何定义“字里行间”?如果直线呈 90°,会发生什么?

标签: algorithm matlab math algebra integrate


【解决方案1】:

假设“线条之间”是指“线条形成的较小角度之内”:

lhS := [-1,+1]x[-1,+1]B 作为S 的边界。

使用l_1l_2 蜜蜂向量将l 转换为l_1 + t*l_2 形式。对 h 做同样的事情。

  • 如果交集不在S 内,则找到lhB 的4 个交集。对它们进行排序,得到一个凸四边形。 Calculate its area
  • 其他:
    • 找到l_2h_2之间的交点pfind the intersection angleα。然后检查:
      • 如果[90°,180°] 中的α[270°,360°] 中的α,则交换lh
      • 如果α &gt; 180°,设置l_2 = −l_2
    • 设置l_1 := h_1 := p。对正面t 和负面t 执行一次 (从p 沿l_2h_2 向前和向后):
      • 找到lhB的交叉点s_ls_h
      • 如果在B的同一边界上:计算area of triangles_ls_hp
      • 如果在B的相邻边界上:在命中边界之间找到B的角c,并再次对s_ls_hpc这四个点进行排序你得到一个凸四边形并计算它的面积。
      • 如果在相反的边界上,找到B的匹配边(你可以通过查看s_l-p的方向来做到这一点)。使用它的两个角点c_1c_2,您现在有5 个点形成一个多边形。对它们进行排序,使多边形是凸的并且是calculate its area

这仍然是相当多的情况,但我认为没有办法解决这个问题。您还可以通过使用三角形和四边形的多边形公式来稍微简化这一点。

如何对点进行排序以获得凸多边形/四边形:选择其中任何一个为p_1,然后根据角度将其余点排序为p_1

如果你定义一个intersection 函数和一个polygon_area 接受一个点列表,对它们进行排序并返回区域,那么这个算法应该很容易实现。

编辑: 帮助解释评论的图片:

【讨论】:

  • 感谢发帖,仍在努力理解您的回答! ;D thks 指出在较小的角度内确实意味着之间。我有几件事要问您是否可以帮助我:我认为 l_1 是标量而不是向量,对吗?交换 l 和 h 是什么意思?最后,Set l_1 := h_1 := p 是什么意思。对正 t 和负 t 执行一次(从 p 沿 l_2 和 h_2 向前和向后):?
  • 不,l_1 是一个向量——它是直线的“起点”(=直线上的任何点)。这就是为什么我们稍后可以将l_1h_1 都设置为p,因为我们知道plh 上。 “交换lh”的意思是“设置l_1=h_1 和l_2=h_2 并将h_1h_2 设置为之前的l_1l_2
  • 对于“正 t”:说 ls_1s_2 中与 B 相交。现在有一个(标量)t_1,所以p + t_1•l_2 = s_1 和一个(标量)t_2,所以p + t_2•l_2 = s_2。现在其中一个t 将是积极的,其中一个将是消极的。我们知道这一点,因为p 介于s_1s_2 之间。这有帮助吗?
  • 添加了一张图片可能会澄清情况。交换、反转和正/负方向的重点是确保您确实看到的是较小的角度,而不是较宽的角度。但我认为实际上可能不需要交换。
  • 我发布了一个答案,想听听你的 cmets。提前致谢!
【解决方案2】:

我认为my answer to your previous question 在大多数情况下仍然适用。

如果您想计算由两条线的较小角度和正方形边界所包围的区域的面积,那么您可以忘记交点,并忘记所有不同的情况。

你可以利用这个事实

  • 正方形S的面积等于4
  • 这个积分的值

    A = quadgk(@(x) ...
        abs( max(min(line1(x),+1),-1) - max(min(line2(x),+1),-1) ), -1, +1);
    

    给出线之间的面积(有时是大角度,有时是小角度)

  • min(A, S-A) 的值是正确答案(总是小角度)。

【讨论】:

  • +1 的答案,如果我可以再 +1 找到这个新问题 ;D
  • 让我知道您对我的回答有何看法,尽管我相信您的回答更好,因为耗时更少,而且这不是经验近似值。
【解决方案3】:

大家好,谢谢你们的回答,我也想到了一种经验方法来找到线之间的区域,为了讨论和完整性,想分享一下。

如果您在正方形[-1,+1]x[-1,+1] 内取大量随机点,您可以将面积测量为落在两条线之间区域内的点的分数。

这里有一个小sn-p和两张图片来展示不同点数得到的经验结果的不同精度。

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 发布的解决方案花费的时间更长,但正如您所见,您可以使其准确。

  • 点数 = 2000

点数 = 10000

【讨论】:

  • 虽然是一个有趣的想法,但这种方法非常不准确/缓慢。我建议使用网格而不是随机点——这样您可以获得更可预测的结果,然后如果角度很小,您需要多少点才能获得准确的结果也变得很清楚。也许更精确:绝对误差是可控的,但是对于小角度,相对误差会变得很大。如果你拿了很多分,这个方法对于一个实际上相当简单的计算来说会变得非常慢。
  • 您听说过 [Monte Carlo Integration] (en.wikipedia.org/wiki/Monte_Carlo_integration) 吗? :)
  • 抱歉,我正在使用移动设备,但您明白了 :)
  • @Chronial 和 Rody - 感谢大家的反馈,你们在这方面帮助了我很多。我会坚持罗迪的答案,因为它是最快、准确和优雅的答案!
猜你喜欢
  • 1970-01-01
  • 2017-03-02
  • 2012-10-06
  • 2012-10-03
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多