Cut the string a few pixels

I am drawing a custom business object diagram using .NET GDI +. Among other things, a diagram consists of several lines connecting objects.

In a specific scenario, I need to shorten the line by a certain number of pixels, say, 10 pixels, that is, find a point on the line that lies 10 pixels earlier than the end point of the line.

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

Illustration

How to calculate the point marked with a red circle, that is, the intersection between the circle and the line? This will give me a new endpoint for the line, cutting it by 10 pixels.


Decision

, . "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);
  }
}
+12
3

, .. ( ) B = (x2, y2) A = (x1, y1), AB = B - A. , ( Math.Sqrt(xx + yy)). 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)

+14

. 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
+5

, . , (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)

The distance between (x3,y3)and (x1,y1)is sqrt (3.192501947 2 + 7.753219015 2 ) or 8.384776311, a difference of 10 with an accuracy of one part in a thousand million, and this is only due to rounding errors on my calculator.

+5
source

Source: https://habr.com/ru/post/1724041/


All Articles