由多个像素的缩短的线多个、像素

由网友(扯淡你的卖弄)分享简介:我画使用.NET GDI +业务对象的自定义图。在其他方面,该图由所连接的对象的几行。在一个特定的情况下,我需要缩短一个线的像素的具体数量,让我们说10个象素,即发现在该位于10个像素的行的结束点之前的行中的点想象与半径的研究的= 10个像素,并且与开始点的线(X1,Y1)和结束点(X2,Y2)的圆。圆的中心位于线的终...

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

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

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

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

解决方案

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

具体而言,我试图把一个函数,可以带圆角画一条线,可以发现,here.

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

  双DX = endPoint.X  -  startPoint.X;
  双DY = endPoint.Y  -  startPoint.Y;
  如果(DX == 0)
  {
    // 垂线:
    如果(endPoint.Y< startPoint.Y)
      endPoint.Y  -  = pixelCount;
    其他
      endPoint.Y + = pixelCount;
  }
  否则,如果(DY == 0)
  {
    //横线:
    如果(endPoint.X< 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);
  }
}
 
2017版AI,资源导出,为什么长和宽,都多一个像素

解决方案

找到方向向量,即让位置向量是(用花车)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)

阅读全文

相关推荐

最新文章