由多个像素的缩短的线 [英] Shorten a line by a number of pixels

查看:180
本文介绍了由多个像素的缩短的线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我画使用.NET GDI +业务对象的自定义图。在其他方面,该图由所连接的对象的几行。

在一个特定的情况下,我需要缩短一个线的像素的具体数量,让我们说10个象素,即发现在该位于10个像素的行的结束点之前的行中的点

想象与半径的研究的= 10个像素,并且与开始点的线(X1,Y1)和结束点(X2,Y2)的圆。圆的中心位于线的终点,如以下图示。

我如何计算出标有红色圆圈的点,即圆和直线的交点?这将使我行的新终点,10个像素缩短了。


解决方案

感谢您的答案,从中我能够放在一起以下步骤。我把它命名为LengthenLine,因为我觉得它更自然地传递像素负数,如果我想行缩短了。

具体而言,我试图把一个函数,可以带圆角画一条线,可以发现,<一个href="http://stackoverflow.com/questions/1805582/net-gdi-drawing-lines-with-rounded-corners">here.

 公共无效LengthenLine(的PointF的startPoint,裁判的PointF端点浮动pixelCount)
{
  如果(startPoint.Equals(终点))
    返回; //不是一条线

  双DX = endPoint.X  -  startPoint.X;
  双DY = endPoint.Y  -  startPoint.Y;
  如果(DX == 0)
  {
    // 垂线:
    如果(endPoint.Y&LT; startPoint.Y)
      endPoint.Y  -  = pixelCount;
    其他
      endPoint.Y + = pixelCount;
  }
  否则,如果(DY == 0)
  {
    //横线:
    如果(endPoint.X&LT; startPoint.X)
      endPoint.X  -  = pixelCount;
    其他
      endPoint.X + = pixelCount;
  }
  其他
  {
    //非水平非垂直线:
    双长度=的Math.sqrt(DX * DX + DY * DY);
    双刻度=(长+ pixelCount)/长;
    DX * =规模;
    DY * =规模;
    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的原始长度减去圆的半径,并添加回线起始位置:

 双DX = X2  -  X1;
双DY = Y2  -  Y1;
双长度=的Math.sqrt(DX * DX + DY * DY);
如果(长度大于0)
{
    DX / =长度;
    DY / =长度;
}
DX * =长度 - 半径;
DY * =长度 - 半径;
INT X3 =(INT)(X1 + DX);
INT Y3 =(INT)(Y1 + DY);
 

编辑:修正了code,aaand固定在最初的解释(以为你想线路从圆的中心,其周边出门:P)

I'm drawing a custom diagram of business objects using .NET GDI+. Among other things, the diagram consists of several lines that are connecting the objects.

In a particular scenario, I need to shorten a line by a specific number of pixels, let's say 10 pixels, i.e. find the point on the line that lies 10 pixels before the end point of the line.

Imagine a circle with radius r = 10 pixels, and a line with start point (x1, y1) and end point (x2, y2). The circle is centered at the end point of the line, as in the following illustration.

How do I calculate the point marked with a red circle, i.e. the intersection between circle and line? This would give me the new end point of the line, shortening it by 10 pixels.


Solution

Thank you for your answers from which I was able to put together the following procedure. I named it LengthenLine, since I find it more natural to pass a negative number of pixels if I want the line shortened.

Specifically, I was trying to put together a function that could draw a line with rounded corners, which can be found here.

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);
  }
}

解决方案

Find the direction vector, i.e. let the position vectors be (using floats) B = (x2, y2) and A = (x1, y1), then AB = B - A. Normalize that vector by dividing by its length ( Math.Sqrt(x*x + y*y) ). Then multiply the direction vector AB by the original length minus the circle's radius, and add back to the lines starting position:

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);

Edit: Fixed the code, aaand fixed the initial explanation (thought you wanted the line to go out from the circle's center to its perimeter :P)

这篇关于由多个像素的缩短的线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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