相关文章推荐
深情的脆皮肠  ·  扒一扒.net、.net ...·  6 月前    · 
大方的柑橘  ·  杂记 ...·  6 月前    · 

之前遇到一个数学问题,如何判断某一线段是否穿过封闭区域?由于很急,在网上胡乱找了一下解决方案,但是没有解决到实际问题。

已知:矩形的四个顶点,线段的起始点,

求:判断线段是否经过改矩形。(如图,红线穿过封闭区域,绿线不穿过封闭区域。)

问题类似于 如何判断某一线段是否穿过封闭区域? 道理就是那个道理,我在那里拿的图。

由于时间关系,我就叫同事帮我写个通用方法,他略微思索,百度了一下,觉得用中学知识就可以解决这个问题,欣然就答应了。代码如下:

    public static bool IsPassThroughRect(List<Vector2> VectList, Vector2 begin, Vector2 end)
        //求直线公式
        double k, b;
        k = (begin.y - end.y) / (begin.x - end.x);
        b = begin.y - begin.x * k;
        int count = 0;
        for (int i = 0; i < VectList.Count; i++)
            if ((VectList[i].y - k * VectList[i].x - b) > 0)
                count++;
                count--;
        if (count == 4 || count == -4)
            return false;
            return true;

  他给我解释了一下:

    将直线写成y=kx+b的形式,将图形的所有顶点坐标带入y-kx-b。

    如果得到的结果同时大于零或者同时小于零,说明图形的所有顶点都在直线的同侧,即直线不过图形。否则说明图形的顶点分布在直线两侧,直线过图形。

    主要是思想就是中学知识:

(1)y-kx-b=0  点刚好在直线上。

(2)y-kx-b>0  点在直线上方。

(3)y-kx-b<0  点在直线下方。

我看了一下,好像是这个道理,直接将参数传进去,测试了一下,结果发现,这个道理虽然是这个道理,但是所用的知识是点与线的关系。这里的需求是线段与矩形的关系,如果是线段的话,这样是不满足需求的。

发现这个问题的时候,都十点半了,其他同事都下班了,看见主程还在,遂问了一下是否有类似的通用方法,结果真有!

代码如下:

 /// <summary>
    /// 线段与矩形是否相交
    /// </summary>
    /// <param name="linePointX1"></param>
    /// <param name="linePointY1"></param>
    /// <param name="linePointX2"></param>
    /// <param name="linePointY2"></param>
    /// <param name="rectangleLeftTopX"></param>
    /// <param name="rectangleLeftTopY"></param>
    /// <param name="rectangleRightBottomX"></param>
    /// <param name="rectangleRightBottomY"></param>
    /// <returns></returns>
    public static bool isLineIntersectRectangle(float linePointX1,
                                      float linePointY1,
                                    float linePointX2,
                                     float linePointY2,
                                     float rectangleLeftTopX,
                                      float rectangleLeftTopY,
                                      float rectangleRightBottomX,
                                      float rectangleRightBottomY)
        float lineHeight = linePointY1 - linePointY2;
        float lineWidth = linePointX2 - linePointX1;  // 计算叉乘 
        float c = linePointX1 * linePointY2 - linePointX2 * linePointY1;
        if ((lineHeight * rectangleLeftTopX + lineWidth * rectangleLeftTopY + c >= 0 && lineHeight * rectangleRightBottomX + lineWidth * rectangleRightBottomY + c <= 0)
            || (lineHeight * rectangleLeftTopX + lineWidth * rectangleLeftTopY + c <= 0 && lineHeight * rectangleRightBottomX + lineWidth * rectangleRightBottomY + c >= 0)
            || (lineHeight * rectangleLeftTopX + lineWidth * rectangleRightBottomY + c >= 0 && lineHeight * rectangleRightBottomX + lineWidth * rectangleLeftTopY + c <= 0)
            || (lineHeight * rectangleLeftTopX + lineWidth * rectangleRightBottomY + c <= 0 && lineHeight * rectangleRightBottomX + lineWidth * rectangleLeftTopY + c >= 0))
            if (rectangleLeftTopX > rectangleRightBottomX)
                float temp = rectangleLeftTopX;
                rectangleLeftTopX = rectangleRightBottomX;
                rectangleRightBottomX = temp;
            if (rectangleLeftTopY < rectangleRightBottomY)
                float temp1 = rectangleLeftTopY;
                rectangleLeftTopY = rectangleRightBottomY;
                rectangleRightBottomY = temp1;
            if ((linePointX1 < rectangleLeftTopX && linePointX2 < rectangleLeftTopX)
                || (linePointX1 > rectangleRightBottomX && linePointX2 > rectangleRightBottomX)
                || (linePointY1 > rectangleLeftTopY && linePointY2 > rectangleLeftTopY)
                || (linePointY1 < rectangleRightBottomY && linePointY2 < rectangleRightBottomY))
                return false;
                return true;
            return false;

他说他也是在网上扒下来的,我没细想,直接改成通用方法,传入我的参数,测试了几次,发现问题解决了。愉快下班!!!

今天发现(判断线段和矩形是否相交 )这篇文章好像就是原文,只是他是用JavaScript写的。大概就是扒的他了吧!

如何判断两个线段\矩形相交? 首先来判断两个线段的情况:假设有两个线段A和B,左右端点分别为A1,A2和B1,B2,分别考虑下面两种情况 1. 线段A在线段B的左边,即A1 A2 2. 线段A在线段B的右边,即A1> B1,那么 A,B不相交的条件是 B1 B2 那么将上面两种情况综合起来考虑就是Min(A2,B2) - Max(A1,B1) =0,那么X就是相交的区域大小。
这里的矩形指的是边与坐标轴平行的矩形,可用x和y上最大最小值表示。 判断是否相交,先快速排斥,再做跨立,通过向量的叉积判断矩形的四个顶点是否线段的两侧,是说明有交集。 (如果判断矩形的边是否有交集的话,可判断线段是否
Description You are to write a program that has to decide whether a given line segment intersects a given rectangle. An example: line: start point: (4,9) end point: (11,2) rect...
判断线段AB是否矩形范围有交集这里的矩形指的是边与坐标轴平行的矩形,可用x和y上最大最小值表示。判断是否相交,先快速排斥,再做跨立,通过向量的叉积判断矩形的四个顶点是否线段的两侧,是说明有交集。(如果判断矩形的边是否有交集的话,可判断线段是否矩形的每条边是否有交集,线段线段的交集判断。)这里在介绍另外一种方法,降维的方法:例如,有线段AB和矩形MN,如图所示:通过M和N点的y坐标计算直线AB上的D和C点,B和C点中取y值小的点B,A和D点中取y值大的点D,最后确定了线段BD在x轴上的投影GH,矩形
bool clipLine( // true if any part of line in imgRect cv::Rect imgRect, // rectangle to clip to cv::Point& pt1, // first endpoint of line overwritten cv::Point& pt2 // second endpoint of line, 在这个示例中,我们首先定义了一个由四个点组成的正方形(x和y分别代表正方形四个角上的x和y坐标)。然后,我们使用了plt.plot函数来绘制这个正方形,并设置linestyle参数为'-'(实线),marker参数为's'(正方形)。 通过设置mec参数(marker edge color)为'blue',我们指定了边界颜色为蓝色。而通过设置mfc参数(marker face color)为'none',我们将内部颜色设置为透明,实现了空心效果。 最后,我们通过设置坐标轴范围和调用plt.show()来显示图形。您可以根据需要调整参数和样式来满足您的要求。