更新

>我在C#中的原始实现
>我在C#中的最终实现,基于我得到的答案.

鉴于以下条件,我如何以编程方式找到两条线之间的重叠段?

另外,对于不同的斜率:

对于垂直线:

对于水平线:

注意:对于所有象限!

我从编码所有可能的条件开始,但它变得丑陋.

public Line Getoverlap (Line line1,Line line2)
{
    double line1X1 = line1.X1;
    double line1Y1 = line1.Y1;
    double line1X2 = line1.X2;
    double line1Y2 = line1.Y2;
    double line2X1 = line2.X1;
    double line2Y1 = line2.Y1;
    double line2X2 = line2.X2;
    double line2Y2 = line2.Y2;

    if (line1X1 > line1X2)
    {
        double swap = line1X1;
        line1X1 = line1X2;
        line1X2 = swap;

        swap = line1Y1;
        line1Y1 = line1Y2;
        line1Y2 = swap;
    }
    else if (line1X1.AlmostEqualTo (line1X2))
    {
        if (line1Y1 > line1Y2)
        {
            double swap = line1Y1;
            line1Y1 = line1Y2;
            line1Y2 = swap;

            swap = line1X1;
            line1X1 = line1X2;
            line1X2 = swap;
        }
    }

    if (line2X1 > line2X2)
    {
        double swap = line2X1;
        line2X1 = line2X2;
        line2X2 = swap;

        swap = line2Y1;
        line2Y1 = line2Y2;
        line2Y2 = swap;
    }
    else if (line2X1.AlmostEqualTo (line2X2))
    {
        if (line2Y1 > line2Y2)
        {
            double swap = line2Y1;
            line2Y1 = line2Y2;
            line2Y2 = swap;

            swap = line2X1;
            line2X1 = line2X2;
            line2X2 = swap;
        }
    }

    double line1MinX = Math.Min (line1X1,line1X2);
    double line2MinX = Math.Min (line2X1,line2X2);
    double line1MinY = Math.Min (line1Y1,line1Y2);
    double line2MinY = Math.Min (line2Y1,line2Y2);
    double line1MaxX = Math.Max (line1X1,line1X2);
    double line2MaxX = Math.Max (line2X1,line2X2);
    double line1MaxY = Math.Max (line1Y1,line1Y2);
    double line2MaxY = Math.Max (line2Y1,line2Y2);

    double overlap;
    if (line1MinX < line2MinX)
        overlap = Math.Max (line1X1,line1X2) - line2MinX;
    else
        overlap = Math.Max (line2X1,line2X2) - line1MinX;

    if (overlap <= 0)
        return null;

    double x1;
    double y1;
    double x2;
    double y2;

    if (line1MinX.AlmostEqualTo (line2MinX))
    {
        x1 = line1X1;
        x2 = x1;
        y1 = line1MinY < line2MinY
                 ? line2Y1
                 : line1Y1;
        y2 = line1MaxY < line2MaxY
                 ? line1Y2
                 : line2Y2;
    }
    else
    {
        if (line1MinX < line2MinX)
        {
            x1 = line2X1;
            y1 = line2Y1;
        }
        else
        {
            x1 = line1X1;
            y1 = line1Y1;
        }

        if (line1MaxX > line2MaxX)
        {
            x2 = line2X2;
            y2 = line2Y2;
        }
        else
        {
            x2 = line1X2;
            y2 = line1Y2;
        }
    }

    return new Line (x1,y1,x2,y2);
}

我确定存在一个算法,但我无法在网上找到一个.

根据我得到的答案更新解决方案:

这个解决方案解释了我能想到的所有情况(垂直,水平,正斜率,负斜率,不相交)

public Line Getoverlap (Line line1,Line line2)
{
    double slope = (line1.Y2 - line1.Y1)/(line1.X2 - line1.X1);
    bool isHorizontal = AlmostZero (slope);
    bool isDescending = slope < 0 && !isHorizontal;
    double invertY = isDescending || isHorizontal ? -1 : 1;

    Point min1 = new Point (Math.Min (line1.X1,line1.X2),Math.Min (line1.Y1*invertY,line1.Y2*invertY));
    Point max1 = new Point (Math.Max (line1.X1,Math.Max (line1.Y1*invertY,line1.Y2*invertY));

    Point min2 = new Point (Math.Min (line2.X1,line2.X2),Math.Min (line2.Y1*invertY,line2.Y2*invertY));
    Point max2 = new Point (Math.Max (line2.X1,Math.Max (line2.Y1*invertY,line2.Y2*invertY));

    Point minIntersection;
    if (isDescending)
        minIntersection = new Point (Math.Max (min1.X,min2.X),Math.Min (min1.Y*invertY,min2.Y*invertY));
    else
        minIntersection = new Point (Math.Max (min1.X,Math.Max (min1.Y*invertY,min2.Y*invertY));

    Point maxIntersection;
    if (isDescending)
        maxIntersection = new Point (Math.Min (max1.X,max2.X),Math.Max (max1.Y*invertY,max2.Y*invertY));
    else
        maxIntersection = new Point (Math.Min (max1.X,Math.Min (max1.Y*invertY,max2.Y*invertY));

    bool intersect = minIntersection.X <= maxIntersection.X && 
                     (!isDescending && minIntersection.Y <= maxIntersection.Y ||
                       isDescending && minIntersection.Y >= maxIntersection.Y);

    if (!intersect)
        return null;

    return new Line (minIntersection,maxIntersection);
}

public bool AlmostEqualTo (double value1,double value2)
{
    return Math.Abs (value1 - value2) <= 0.00001;
}

public bool AlmostZero (double value)
{
    return Math.Abs (value) <= 0.00001;
}

解决方法

这个问题大致相当于测试两个轴对齐的矩形是否相交:你可以威胁每个段作为轴对齐矩形的对角线,然后你需要找到这两个矩形的交点.以下是我用于矩形交叉的方法.

让我们假设段的斜率是上升的,垂直的或水平的;如果段正在下降,则否定每个y坐标以使它们上升.

为每个线段定义MinPoint和MaxPoint:

Point min1 = new Point(Math.Min(line1.X1,Math.Min(line1.Y1,line1.Y2);
Point max1 = new Point(Math.Max(line1.X1,Math.Max(line1.Y1,line1.Y2);

Point min2 = new Point(Math.Min(line2.X1,Math.Min(line2.Y1,line2.Y2);
Point max2 = new Point(Math.Max(line2.X1,Math.Max(line2.Y1,line2.Y2);

现在交叉点由以下两点给出:两个最小值的最大值,以及两个最大值的最小值

Point minIntersection = new Point(Math.Max(min1.X,Math.Max(min1.Y,min2.Y));
Point maxIntersection = new Point(Math.Min(max1.X,Math.Min(max1.Y,max2.Y));

就是这样.要检查两个段是否相交,请检查

bool intersect = (minIntersection.X< maxIntersection.X) && (minIntersection.Y< maxIntersection.Y);

如果它们相交,则交点由minIntersection和maxIntersection两个点给出.如果它们不相交,则段的长度(minIntersection,maxIntersection)是两个原始段之间的距离.

(如果在第一步中否定了每个y坐标,则现在否定结果的y坐标)

(您可以轻松扩展此方法以覆盖3个或更多维度的共线段)

c# – 用于查找重叠两个共线段的段的算法的更多相关文章

  1. Swift中的集合类数据结构

    在那种情况下,你将会需要一种基本的集合类数据结构。继续学习,你将会比较成熟的Cocoa数据结构与对应的纯Swift结构的性能。常见iOS数据结构iOS中三种最常用的数据结构是arrays,dictionaries和sets。除了在Swift和Objective-C中旧的Foundation框架中的数据结构,现在又有了新的仅支持Swift版本的数据结构与语言紧密结合在一起。Swift数组是同质的,意味着每一个Swift数组都只包含一种类型的对象。

  2. 是Swift词典的索引性能?即使是异国风情(UUID)?

    我想构建一些将保留以便快速搜索的数组.如果我使用这样的东西:请问查询:在对数时间内执行?如果是,对其他类型是否相同:Float,Double,String.最后,我需要它使用UUID类型,它会工作吗?

  3. PHP实现二维数组中的查找算法小结

    这篇文章主要介绍了PHP实现二维数组中的查找算法,涉及PHP数组遍历、判断、计算等相关操作技巧,需要的朋友可以参考下

  4. 详解Python查找算法的实现(线性,二分,分块,插值)

    这篇文章主要为大家介绍了Python中常见的四种查找算法的实现:线性、二分、分块和插值,文中通过图片详细讲解了它们实现的原理与代码,需要的可以参考一下

  5. 如何利用JavaScript实现二叉搜索树

    这篇文章主要给大家介绍了关于如何利用JavaScript实现二叉搜索树的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  6. PHP / MySQL – 查找具有相似或匹配属性的项目

    现在问题由于哈希冲突而缩小为唯一性问题,但我们可以非常确定不匹配的属性.此外,通过使用乘数的大小从生成的数字中提取散列值,这将具有相对容易检查属性是否以不同顺序出现在另一个项目中的优点.HTH.编辑:检查匹配的示例给定项目1和项目2.计算的项目哈希值相等.这是最好的情况.无需进一步计算.给定项目1和项目2.项目的计算哈希值不相等.继续打破财产哈希……

  7. 正则表达式太慢?这里有一个提速100倍的方案附代码

    “当遇到一个文本处理问题时,如果你在第一时间想到了正则表达式,那么恭喜你,你的问题从一个变成了俩!“如果你曾参与过文本数据分析,正则表达式(Regex)对你来说一定不陌生。词库索引、关键词替换……正则表达式的强大功能使其成为了文本处理的必备工具。然而,在处理大文本的情境下,正则表达式的低效率却常常让人抓耳挠腮。今天,文摘菌将为你介绍一款比正则表达式快数百倍的Python库——FlashText。让

  8. php array_intersect()效率

    考虑下面的脚本.只有三个值的两个数组.当我使用array_intersect()比较这两个数组时.结果很快.我的问题是array_intersect()的效率是多少.是否我们比较两个都有1000个值的数组.会产生更好的结果…..我们需要使用一些哈希函数来处理快速找到常用值这将是有效的???..我需要你的建议…

  9. sku组合查询算法探索

    什么是SKU问题来自垂直导购线周会的一次讨论,sku组合查询,这个题目比较俗,是我自己取得。当sku属性只是2×2的时候,还是很容易计算的。演示框最下面是可用的sku组合。如果sku属性组合元素的总和数用m表示,结果数据长度为n,那么每次选择后,需要的算法大致步骤是m*n。正则表达式很不稳定,万一sku组合中有一些特殊字符,就可能导致一个正则匹配没能匹配到我们想要的表达式。

  10. 正则表达式,来自百度百科

    正则表达式编辑正则表达式,又称规则表达式。正则表达式被作为用来描述其称之为“正则集的代数”的一种表达式,因而采用了“正则表达式”这个术语。传统的NFA引擎运行所谓的“贪婪的”匹配回溯算法,以指定顺序测试正则表达式的所有可能的扩展并接受第一个匹配项。因为传统的NFA构造正则表达式的特定扩展以获得成功的匹配,所以它可以捕获子表达式匹配和匹配的反向引用。

随机推荐

  1. c# – (wpf)Application.Current.Resources vs FindResource

    所以,我正在使用C#中的WPF创建一个GUI.它看起来像这样:它现在还没有完成.这两行是我尝试制作一种数据表,它们在XAML中是硬编码的.现在,我正在C#中实现添加新的水果按钮功能.我在XAML中有以下样式来控制行的背景图像应该是什么样子:因此,在代码中,我为每列col0,col1和col2创建一个图像,如果我使用以下代码,它添加了一个如下所示的新行:如你所见,它不太正确……为什么一个似乎忽略了一些属性而另一个没有?

  2. c# – 绑定DataGridTemplateColumn

    似乎我已经打了个墙,试图在DataGrid上使用DataTemplates.我想要做的是使用一个模板来显示每个单元格的两行文本.但是似乎无法以任何方式绑定列.以下代码希望显示我想做的事情.注意每个列的绑定:模板列没有这样的东西,因此,这个xaml不可能工作.我注定要将整个DataTemplate复制到每个列,只是对每个副本都有不同的约束?解决方法我不完全确定你想要做什么,但如果您需要获取整行的DataContext,可以使用RelativeSource绑定来移动视觉树.像这样:

  3. c# – 学习设计模式的资源

    最近我来到了这个设计模式的概念,并对此感到非常热情.你能建议一些帮助我深入设计模式的资源吗?

  4. c# – 是否有支持嵌入HTML页面的跨操作系统GUI框架?

    我想开发一个桌面应用程序来使用跨系统,是否有一个GUI框架,允许我为所有3个平台编写一次代码,并具有完全可脚本化的嵌入式Web组件?我需要它有一个API来在应用程序和网页之间进行交流.我知道C#,JavaScript和一些python.解决方法Qt有这样的事情QWebView.

  5. c# – 通过字符串在对象图中查找属性

    我试图使用任意字符串访问嵌套类结构的各个部分.给出以下(设计的)类:我想要从Person对象的一个实例的“PersonsAddress.HousePhone.Number”获取对象.目前我正在使用反思来做一些简单的递归查找,但是我希望有一些忍者有更好的想法.作为参考,这里是我开发的(crappy)方法:解决方法您可以简单地使用标准的.NETDataBinder.EvalMethod,像这样:

  6. c# – 文件下载后更新页面

    FamilyID=0a391abd-25c1-4fc0-919f-b21f31ab88b7&displaylang=en&pf=true它呈现该页面,然后使用以下元刷新标签来实际向用户提供要下载的文件:你可能需要在你的应用程序中做类似的事情.但是,如果您真的有兴趣在文件完全下载后执行某些操作,那么您的运气不佳,因为没有任何事件可以与浏览器进行通信.执行此操作的唯一方法是上传附件时使用的AJAXupload.

  7. c# – 如何在每个机器应用程序中实现单个实例?

    我必须限制我的.net4WPF应用程序,以便每台机器只能运行一次.请注意,我说每个机器,而不是每个会话.我使用一个简单的互斥体实现单实例应用程序,直到现在,但不幸的是,这样一个互斥是每个会话.有没有办法创建机器互连,还是有其他解决方案来实现每个机器应用程序的单个实例?

  8. c# – WCF和多个主机头

    我的雇主网站有多个主机名,都是同一个服务器,我们只是显示不同的皮肤来进行品牌宣传.不幸的是,在这种情况下,WCF似乎不能很好地工作.我试过overridingthedefaulthostwithacustomhostfactory.这不是一个可以接受的解决方案,因为它需要从所有主机工作,而不仅仅是1.我也看过thisblogpost,但是我无法让它工作,或者不是为了解决我的问题.我得到的错误是“这

  9. c# – ASP.NET MVC模型绑定与表单元素名称中的虚线

    我一直在搜索互联网,试图找到一种方式来容纳我的表单元素的破折号到ASP.NET的控制器在MVC2,3或甚至4中的默认模型绑定行为.作为一名前端开发人员,我更喜欢在我的CSS中使用camelCase或下划线进行破折号.在我的标记中,我想要做的是这样的:在控制器中,我会传入一个C#对象,看起来像这样:有没有办法通过一些正则表达式或其他行为来扩展Controller类来适应这种情况?我讨厌这样的事实,我必须这样做:甚至这个:思考?

  10. c# – 用户界面设计工具

    我正在寻找一个用户界面设计工具来显示文档中可能的GUI.我不能生成代码.我知道MicrosoftVisio提供了一个功能.但有什么办法吗?您使用哪种软件可视化GUI?

返回
顶部