复杂线路背后的逻辑

5
我想从点A画一条线到点B。但是这条线本身应该是智能的,如果点B恰好在点A正下方,则应绘制一条直线。但如果点B在A下面并且水平方向上离A有一定距离,则应以直角方式绘制一条线。希望你能理解我的意思。如果你使用过任何UML工具,如edraw Max或其他工具,你可能已经见过这些类型的线条。有什么办法可以实现这个功能吗?谢谢!
4个回答

4
这里有一些代码:

void connectPoints(Point a, Point b)
{
    Point middlePoint1(a.x, (a.y + b.y)/2);
    Point middlePoint2(b.x, (a.y + b.y)/2);
    drawLine(a, middlePoint1);
    drawLine(middlePoint1, middlePoint2);
    drawLine(middlePoint2, b);
}

为了澄清,提问者实际上想要看起来像这里大多数连接一样的3段轴对齐线: style

你是对的。这正是所期望的行为。让我看看你的代码做了什么。 - TCM

1

直接的方法有什么问题吗?

// pA, pB - points
DrawLine(pA.X, pA.Y, pA.X, pB.Y); // vertical line from A point down/up to B
DrawLine(pA.X, pB.Y, pB.X, pB.Y); // horizontal line to B

基本思路是正确的。更复杂的问题是,OP如何处理多条线相互碰撞的图示?对于这些正交线,实际上有两条线可以画:例如向下和向右,与向右和向下。现在他需要绘制1000个这样的线,给他提供了2^1000种可能的配置空间。他应该绘制哪一条线以最小化线条重叠?他应该绘制哪一条线以避免角点碰撞的线条?难点就在于这个布局问题。 - Ira Baxter
@Ira,回答未提出的问题很困难。我同意这个问题通常很复杂,但是这个具体问题没有那么多细节,所以我认为最简单的方法可能足够了。其他解决方案可能过于复杂,因为我们不知道他真正需要什么。 - Snowbear

1

这是你所说的直角智能吗?伪代码随之而来...

Point pA(x,y);
Point pB(x,y);
if abs(pB.X-pA.X) < abs(pB.Y-pA.Y) // Going vertically or horizontal?
{
    DrawLine(pA.X, pA.Y, pA.X, pB.Y); //Long vertical
    DrawLine(pA.X, pB.Y, pB.X, pB.Y); //Short horizontal
}
else
{
    DrawLine(pA.X, pA.Y, pB.X, pA.Y); //Long horizontal
    DrawLine(pB.X, pA.Y, pB.X, pB.Y); //Short vertical
}

或者对于弯曲的线条(我随口说的):

Point pA=(x,y);
Point pB=(x,y)
if abs(pB.X-pA.X) < abs(pB.Y-pA.Y) // Going vertically or horizontal?
{
    Point pHalfwayY = (pB.Y-pA.Y)/2 + pB.Y
    DrawLine(pA.X, pA.Y, pA.X, pHalfwayY ); //Long vertical 1st half
    DrawLine(pA.X, pHalfwayY , pB.X, pHalfwayY ); //Short horizontal
    DrawLine(pA.X, pHalfwayY , pA.X, pB.Y); //Long vertical 2nd half
}
else
{
    Point pHalfwayX = (pB.X-pA.X)/2 + pB.Y
    DrawLine(pA.X, pA.Y,pHalfwayX , pA.Y); //Long horizontal 1st Half
    DrawLine(pHalfwayX , pA.Y, pHalfwayX , pB.Y); // Short Vertical
    DrawLine(pHalfwayX , pA.Y, pA.X, pB.Y); //Long horizontal 2nd half
}

希望这能有所帮助。

0

GDI+这样的图形库会为您处理这个问题,并根据起点和终点绘制线条。

如果您想自己处理这个问题,您需要使用三角函数来确定线条的旋转角度。


1
这似乎不是他需要的解决方案。我相信他实际上想要仅使用直线(水平/垂直)连接点。尽管描述不是很清楚。 - Snowbear
@Snowbear:你说得对。我只想画水平和垂直线,不需要交叉线。 - TCM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接