给出轨迹折线的中间线,求出轨迹(绘制平行线)
作者:互联网
给出轨迹折线的中间线,求出轨迹(绘制平行线)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DrawRoadAnd.Control
{
using System.Windows;
using Point2D = System.Windows.Point;
public class DrawParallelLines
{
private static void GetParallelLine(Point2D inSPos, Point2D inEPos, double inWidth, bool IsLeft, out Point2D outSPos, out Point2D outEPos)
{
Vector v1 = new Vector(inEPos.X - inSPos.X, inEPos.Y - inSPos.Y);
v1.Normalize();
Vector n1 = new Vector(-v1.Y, v1.X);
if (IsLeft == false)
n1 = -n1;
n1 *= inWidth;
outSPos = inSPos + n1;
outEPos = inEPos + n1;
}
/// <summary>
/// 计算两条直线的交点
/// </summary>
/// <param name="SLine1">L1的点1坐标</param>
/// <param name="ELine1">L1的点2坐标</param>
/// <param name="SLine2">L2的点1坐标</param>
/// <param name="ELine2">L2的点2坐标</param>
/// <returns></returns>
private static Point2D GetIntersection(Point2D SLine1, Point2D ELine1, Point2D SLine2, Point2D ELine2)
{
/*
* L1,L2都存在斜率的情况:
* 直线方程L1: ( y - y1 ) / ( y2 - y1 ) = ( x - x1 ) / ( x2 - x1 )
* => y = [ ( y2 - y1 ) / ( x2 - x1 ) ]( x - x1 ) + y1
* 令 a = ( y2 - y1 ) / ( x2 - x1 )
* 有 y = a * x - a * x1 + y1 .........1
* 直线方程L2: ( y - y3 ) / ( y4 - y3 ) = ( x - x3 ) / ( x4 - x3 )
* 令 b = ( y4 - y3 ) / ( x4 - x3 )
* 有 y = b * x - b * x3 + y3 ..........2
*
* 如果 a = b,则两直线平等,否则, 联解方程 1,2,得:
* x = ( a * x1 - b * x3 - y1 + y3 ) / ( a - b )
* y = a * x - a * x1 + y1
*
* L1存在斜率, L2平行Y轴的情况:
* x = x3
* y = a * x3 - a * x1 + y1
*
* L1 平行Y轴,L2存在斜率的情况:
* x = x1
* y = b * x - b * x3 + y3
*
* L1与L2都平行Y轴的情况:
* 如果 x1 = x3,那么L1与L2重合,否则平等
*
*/
double a = 0, b = 0;
int state = 0;
if (SLine1.X != ELine1.X)
{
a = (ELine1.Y - SLine1.Y) / (ELine1.X - SLine1.X);
state |= 1;
}
if (SLine2.X != ELine2.X)
{
b = (ELine2.Y - SLine2.Y) / (ELine2.X - SLine2.X);
state |= 2;
}
switch (state)
{
case 0: //L1与L2都平行Y轴
{
if (SLine1.X == SLine2.X)
{
//throw new Exception("两条直线互相重合,且平行于Y轴,无法计算交点。");
return new Point2D(0, 0);
}
else
{
//throw new Exception("两条直线互相平行,且平行于Y轴,无法计算交点。");
return new Point2D(0, 0);
}
}
case 1: //L1存在斜率, L2平行Y轴
{
double x = SLine2.X;
double y = (SLine1.X - x) * (-a) + SLine1.Y;
return new Point2D(x, y);
}
case 2: //L1 平行Y轴,L2存在斜率
{
double x = SLine1.X;
//网上有相似代码的,这一处是错误的。你可以对比case 1 的逻辑 进行分析
//源code:lineSecondStar * x + lineSecondStar * lineSecondStar.X + p3.Y;
double y = (SLine2.X - x) * (-b) + SLine2.Y;
return new Point2D(x, y);
}
case 3: //L1,L2都存在斜率
{
if (a == b)
{
// throw new Exception("两条直线平行或重合,无法计算交点。");
return new Point2D(0, 0);
}
double x = (a * SLine1.X - b * SLine2.X - SLine1.Y + SLine2.Y) / (a - b);
double y = a * x - a * SLine1.X + SLine1.Y;
return new Point2D(x, y);
}
}
return new Point2D(0, 0);
}
/// <summary>
///
/// </summary>
/// <param name="inLines"></param>
/// <param name="width"></param>
/// <param name="IsLeft"></param>
/// <returns></returns>
public static List<Point2D> GetParallelLines(List<Point2D> inLines, double width, bool IsLeft)
{
List<Point2D> tempPoints = new List<Point2D>();
for (int i = 0; i < inLines.Count - 1; i++)
{
Point2D p1, p2, p3, p4;
if (tempPoints.Count == 0)
{
GetParallelLine(inLines[0], inLines[1], width, IsLeft, out p1, out p2);
tempPoints.Add(p1); tempPoints.Add(p2);
continue;
}
if (inLines[i].X == inLines[i + 1].X && inLines[i].Y == inLines[i + 1].Y)
{
continue;
}
GetParallelLine(inLines[i], inLines[i+1], width, IsLeft, out p3, out p4);
Point2D IntersectPoint = GetIntersection(tempPoints[tempPoints.Count - 2], tempPoints[tempPoints.Count - 1], p3, p4);
tempPoints.RemoveAt(tempPoints.Count - 1);
tempPoints.Add(IntersectPoint);
tempPoints.Add(p4);
}
return tempPoints;
}
}
}
标签:轨迹,中间线,L2,tempPoints,SLine1,折线,L1,new,Point2D 来源: https://blog.csdn.net/g_idea/article/details/113894522