缩短一行像素数

ber*_*hof 12 .net c# geometry drawing gdi+

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

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

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

插图http://i45.tinypic.com/140b5w5.gif

如何计算用红色圆圈标记的点,即圆与线之间的交点?这将为我提供该线的新终点,将其缩短10个像素.


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

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

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

Cec*_*ame 14

找到方向向量,即让位置向量为(使用浮点数)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);
Run Code Online (Sandbox Code Playgroud)

编辑:修复了代码,aaand修复了初始解释(想想你想让这条线从圆圈的中心走到它的周边:P)


unh*_*ler 5

http://i50.tinypic.com/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

  • 请记住,您必须注意斜率无限或零(即垂直和水平线)或足够接近导致溢出的情况 - 在这种情况下,您的分区将失败. (2认同)

pax*_*blo 5

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

(x2+p*(x1-x2),y2+p*(y1-y2))
Run Code Online (Sandbox Code Playgroud)

这里p是沿着你想要走线的百分比.

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

p = r/L
Run Code Online (Sandbox Code Playgroud)

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

(x2+(10/L)*(x1-x2),y2+(10/L)*(y1-y2))
Run Code Online (Sandbox Code Playgroud)

例如,如果你有两个点,(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)
Run Code Online (Sandbox Code Playgroud)

(x3,y3)和之间的距离(x1,y1)是sqrt(3.192501947 2 + 7.753219015 2)或8.384776311,十亿分之一到十亿分之一,这只是因为我的计算器出现舍入错误.