缩短一行像素数

我正在使用.NET GDI +绘制业务对象的自定义图表。 除此之外,该图由连接对象的几行组成。

在特定场景中,我需要将一条线缩短特定数量的像素,比方说10个像素,即找到线的终点之前10个像素的线上的点。

想象一个半径为r = 10像素的圆,以及一条带有起点(x1,y1)和终点(x2,y2)的直线。 圆圈以线的终点为中心,如下图所示。

插图http://sofzh.miximages.com/c%23/140b5w5.gif

如何计算用红色圆圈标记的点,即圆与线之间的交点? 这会给我一个新的终点,缩短10个像素。


感谢您的答案,我可以将以下程序放在一起。 我将它命名为LengthenLine,因为如果我想缩短线条,我发现传递负像素数更自然。

具体来说,我试图组合一个可以绘制圆角线的function,可以在这里找到。

public void LengthenLine(PointF startPoint, ref PointF endPoint, float pixelCount) { if (startPoint.Equals(endPoint)) return; // not a line double dx = endPoint.X - startPoint.X; double dy = endPoint.Y - startPoint.Y; if (dx == 0) { // vertical line: if (endPoint.Y < startPoint.Y) endPoint.Y -= pixelCount; else endPoint.Y += pixelCount; } else if (dy == 0) { // horizontal line: if (endPoint.X < startPoint.X) endPoint.X -= pixelCount; else endPoint.X += pixelCount; } else { // non-horizontal, non-vertical line: double length = Math.Sqrt(dx * dx + dy * dy); double scale = (length + pixelCount) / length; dx *= scale; dy *= scale; endPoint.X = startPoint.X + Convert.ToSingle(dx); endPoint.Y = startPoint.Y + Convert.ToSingle(dy); } } 

找到方向向量,即让位置向量为(使用浮点数)B =(x2,y2)和A =(x1,y1),然后AB = B – A.通过除以其长度(Math.Sqrt)对该向量进行归一化(x x + y y))。 然后将方向向量AB乘以原始长度减去圆的半径,并加回到起始位置的行:

 double dx = x2 - x1; double dy = y2 - y1; double length = Math.Sqrt(dx * dx + dy * dy); if (length > 0) { dx /= length; dy /= length; } dx *= length - radius; dy *= length - radius; int x3 = (int)(x1 + dx); int y3 = (int)(y1 + dy); 

编辑:修复了代码,aaand修复了初始解释(想想你想让线从圆圈的中心向外围移动:P)

http://sofzh.miximages.com/c%23/nz165z.png

您可以使用类似的三角形。 对于主三角形, d是斜边, r的延伸是符合直角的垂直线。 在圆圈内,你将有一个较小的三角形,其长度为r的斜边。

 r / d =(x2-a0)/(x2-x1)=(y2-b0)/(y2-y1)

 a0 = x2 +(x2-x1)r / d

 b0 = y2 +(y2-y1)r / d

我不知道为什么你甚至不得不介绍这个圈子。 对于从(x2,y2)(x1,y1) ,您可以计算该线上的任何点:

 (x2+p*(x1-x2),y2+p*(y1-y2)) 

其中p是你想去的线的百分比。

要计算百分比,您只需要:

 p = r/L 

所以在你的情况下, (x3,y3)可以计算为:

 (x2+(10/L)*(x1-x2),y2+(10/L)*(y1-y2)) 

例如,如果你有两个点(x2=1,y2=5)(x1=-6,y1=22) ,它们的长度为sqrt(7 2 + 17 2或18.38477631和10除以它是0.543928293。将所有这些数字放入上面的等式中:

  (x2 + (10/l) * (x1-x2) , y2 + (10/l) * (y1-y2)) = (1 + 0.543928293 * (-6- 1) , 5 + 0.543928293 * (22- 5)) = (1 + 0.543928293 * -7 , 5 + 0.543928293 * 17 ) = (x3=-2.807498053,y3=14.24678098) 

(x3,y3)(x1,y1)之间的距离是sqrt(3.192501947 2 + 7.753219015 2 )或8.384776311,相差十亿到十亿分之一,这只是因为计算器上的舍入误差。