Skróć linię o liczbę pikseli
Rysuję niestandardowy diagram obiektów biznesowych za pomocą .NET GDI +. Między innymi diagram składa się z kilku linii łączących obiekty.
W konkretnym scenariuszu muszę skrócić linię o określoną liczbę pikseli, powiedzmy 10 pikseli, tj. Znaleźć punkt na linii, który leży 10 pikseli przed końcowym punktem linii.
Wyobraź sobie okrąg o promieniur = 10 pikseli i linia z punktem początkowym (x1, y1) i punktem końcowym (x2, y2). Okrąg jest wyśrodkowany w punkcie końcowym linii, jak na poniższej ilustracji.
Ilustracja http://i45.tinypic.com/140b5w5.gif
Jak obliczyć punkt oznaczony czerwonym kółkiem, tj. Przecięcie między okręgiem a linią? Dałoby mi to nowy punkt końcowy linii, skracając go o 10 pikseli.
RozwiązanieDziękuję za odpowiedzi, z których udało mi się zebrać następującą procedurę. Nazwałem go LengthenLine, ponieważ uważam, że bardziej naturalne jest przekazywanie ujemnej liczby pikseli, jeśli chcę skrócić linię.
W szczególności próbowałem stworzyć funkcję, która mogłaby narysować linię z zaokrąglonymi rogami, które można znaleźćtutaj.
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);
}
}