检测两个重合线段重合的子集 [英] Detecting coincident subset of two coincident line segments

查看:184
本文介绍了检测两个重合线段重合的子集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题涉及到:

  • <一个href="http://stackoverflow.com/questions/153592/how-do-i-determine-the-intersection-point-of-two-lines-in-gdi">How我做决定的交汇点在GDI两行+?(代数很好的解释,但没有code)
  • <一个href="http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect/563240#563240">How你发现,其中两条线段相交?(接受的答案实际上不工作)
  • How do I determine the intersection point of two lines in GDI+? (great explanation of algebra but no code)
  • How do you detect where two line segments intersect? (accepted answer doesn't actually work)

但要注意,一个有趣的子问题是,在大多数的解决方案,只是返回null为一致的情况下,即使有三子的情况下完全掩盖了:

But note that an interesting sub-problem is completely glossed over in most solutions which just return null for the coincident case even though there are three sub-cases:

  • 一致,但不重叠
  • 在刚刚接触点和重合
  • 在重叠/子段重合行

例如,我们可以设计一个C#的功能是这样的:

For example we could design a C# function like this:

public static PointF[] Intersection(PointF a1, PointF a2, PointF b1, PointF b2)

其中,(A1,A2)是一个线段和(B1,B2)是另一个

where (a1,a2) is one line segment and (b1,b2) is another.

此功能需要涵盖所有的怪异的情况下,大多数的实现或解释粉饰。为了解释的重合线的古怪,函数可以返回的PointF的数组:

This function would need to cover all the weird cases that most implementations or explanations gloss over. In order to account for the weirdness of coincident lines, the function could return an array of PointF's:

  • 在零结果点(或空),如果线是平行的或不相交(无限线相交,但线段的不相交或线并行
  • 一个结果点(含路口位置),如果他们这样做的相交或如果他们的一致在一个点上
  • 在两个结果点(在重叠部分线段),如果两行是一致
  • zero result points (or null) if the lines are parallel or do not intersect (infinite lines intersect but line segments are disjoint, or lines are parallel)
  • one result point (containing the intersection location) if they do intersect or if they are coincident at one point
  • two result points (for the overlapping part of the line segments) if the two lines are coincident

推荐答案

听起来像是你有你的解决方案,这是伟大的。我有一些建议,以改善它。

Sounds like you have your solution, which is great. I have some suggestions for improving it.

该方法有一个主要的可用性问题,因为它是非常混乱理解(1)中的参数将在平均什么,和(2)什么结果出来平均值。两者都是,你必须搞清楚,如果你想使用的方法有点困惑。

The method has a major usability problem, in that it is very confusing to understand (1) what the parameters going in mean, and (2) what the results coming out mean. Both are little puzzles that you have to figure out if you want to use the method.

我会更倾向于使用类型系统这是什么方法做,使之更加清晰。

I would be more inclined to use the type system to make it much more clear what this method does.

我会先定义一个类型 - 也许是一个结构,特别是当它是将是不可改变的 - 所谓LineSegment。一个LineSegment由两个的PointF结构重新presenting终点。

I'd start by defining a type -- perhaps a struct, particularly if it was going to be immutable -- called LineSegment. A LineSegment consists of two PointF structs representing the end point.

二,我会定义一个抽象基类轨迹和派生类型EmptyLocus,PointLocus,LineSegmentLocus也许UnionLocus如果你需要重新present轨迹是两个或多个位点的联合。一个空轨迹是仅仅一个单,一个点轨迹是只是一个单一的点,等等。

Second, I would define an abstract base type "Locus" and derived types EmptyLocus, PointLocus, LineSegmentLocus and perhaps UnionLocus if you need to represent the locus that is the union of two or more loci. An empty locus is just a singleton, a point locus is just a single point, and so on.

现在你的方法的签名变得更加清晰:

Now your method signature becomes much more clear:

static Locus Intersect(LineSegment l1, LineSegment l2)

此方法需要两个线段,并且计算的点的轨迹是它们的交集 - 无论是空的,一个单一的点,或者一个线段

This method takes two line segments and computes the locus of points that is their intersection -- either empty, a single point, or a line segment.

请注意,您就可以概括这个方法。计算的线段与线段的交点是棘手的,但计算的线段与点,或具有一个点一个点,或任何用空轨迹的交点是容易的。而且这并不难路口延伸到基因位点的任意工会。因此,你实际上可以写:

Note that you can then generalize this method. Computing the intersection of a line segment with a line segment is tricky, but computing the intersection of a line segment with a point, or a point with a point, or anything with the empty locus is easy. And it's not hard to extend intersection to arbitrary unions of loci. Therefore, you could actually write:

static Locus Intersect(Locus l1, Locus l2)

哎,现在它变得清晰,相交可能是在轨迹的延伸方式:

And hey, now it becomes clear that Intersect could be an extension method on locus:

static Locus Intersect(this Locus l1, Locus l2)

从的PointF添加的隐式转换PointLocus和LineSegment到LineSegmentLocus,你可以说这样的话

Add an implicit conversion from PointF to PointLocus and LineSegment to LineSegmentLocus, and you can say things like

var point = new PointF(whatever);
var lineseg = new LineSegment(somepoint, someotherpoint);
var intersection = lineseg.Intersect(point);
if (intersection is EmptyLocus) ...

使用的类型系统以及可大规模提高程序的可读性。

Using the type system well can massively improve the readability of a program.

这篇关于检测两个重合线段重合的子集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆