/// <summary>
/// 通过中心线关键点获取左右辅助线关键点
/// </summary>
/// <param name="centerPoints">中心线关键点</param>
/// <param name="leftWidth">道路左距离</param>
/// <param name="rightWidth">道路右距离</param>
/// <returns>左右辅助线的点集合</returns>
private Tuple<Point[], Point[]> GetAuxiliaryLinePointsByCenterLinePoints(Collection<Point> centerPoints, double leftWidth, double rightWidth)
{
int pointCount = centerPoints.Count;
Point[] leftPoints = new Point[pointCount],
rightPoints = new Point[pointCount];
for (int i = 1; i < pointCount; i++)
{
if (centerPoints[i].X.Equals(centerPoints[i - 1].X))
{
if (centerPoints[i].Y > centerPoints[i - 1].Y)
{
leftPoints[i - 1] = new Point(centerPoints[i - 1].X - leftWidth, centerPoints[i - 1].Y);
leftPoints[i] = new Point(centerPoints[i].X - leftWidth, centerPoints[i].Y);
rightPoints[i - 1] = new Point(centerPoints[i - 1].X + rightWidth, centerPoints[i - 1].Y);
rightPoints[i] = new Point(centerPoints[i].X + rightWidth, centerPoints[i].Y);
}
else
{
leftPoints[i - 1] = new Point(centerPoints[i - 1].X + leftWidth, centerPoints[i - 1].Y);
leftPoints[i] = new Point(centerPoints[i].X + leftWidth, centerPoints[i].Y);
rightPoints[i - 1] = new Point(centerPoints[i - 1].X - rightWidth, centerPoints[i - 1].Y);
rightPoints[i] = new Point(centerPoints[i].X - rightWidth, centerPoints[i].Y);
}
}
else
{
Point[] pointsleft1 =
GetPointsOfDistanceToPointOnTheLine(new Point[] { centerPoints[i - 1], centerPoints[i] },
leftWidth, true);
Point[] pointsleft2 =
GetPointsOfDistanceToPointOnTheLine(new Point[] { centerPoints[i - 1], centerPoints[i] },
leftWidth, false);
Point[] pointsRight1 =
GetPointsOfDistanceToPointOnTheLine(new Point[] { centerPoints[i - 1], centerPoints[i] },
rightWidth, true);
Point[] pointsRight2 =
GetPointsOfDistanceToPointOnTheLine(new Point[] { centerPoints[i - 1], centerPoints[i] },
rightWidth, false);
if (centerPoints[i].Y > centerPoints[i - 1].Y)
{
leftPoints[i - 1] = pointsleft1[0];
leftPoints[i] = pointsleft2[0];
rightPoints[i - 1] = pointsRight1[1];
rightPoints[i] = pointsRight2[1];
}
else
{
leftPoints[i - 1] = pointsleft1[1];
leftPoints[i] = pointsleft2[1];
rightPoints[i - 1] = pointsRight1[0];
rightPoints[i] = pointsRight2[0];
}
}
if (i != 1)
{
Point tempLeftPoint, tempRightPoint;
tempLeftPoint = leftPoints[i - 1];
tempRightPoint = rightPoints[i - 1];
Point[] leftOutsideRoadPoints = new Point[4];
leftOutsideRoadPoints[0] = leftPoints[i - 2];
leftOutsideRoadPoints[1] = leftPoints[i - 1];
leftOutsideRoadPoints[2] = tempLeftPoint;
leftOutsideRoadPoints[3] = leftPoints[i];
Point leftIntersectiony = GetIntersectionyOfTwoLines(leftOutsideRoadPoints);
leftPoints[i - 1] = leftIntersectiony;
Point[] rightOutsideRoadPoints = new Point[4];
rightOutsideRoadPoints[0] = rightPoints[i - 2];
rightOutsideRoadPoints[1] = rightPoints[i - 1];
rightOutsideRoadPoints[2] = tempRightPoint;
rightOutsideRoadPoints[3] = rightPoints[i];
Point rightIntersectiony = GetIntersectionyOfTwoLines(rightOutsideRoadPoints);
rightPoints[i - 1] = rightIntersectiony;
}
}
return new Tuple<Point[], Point[]>(leftPoints, rightPoints);
}
/// <summary>
/// 求到直线固定点、固定距离的点坐标
/// </summary>
/// <param name="linePoint">确定一条直线的两个点</param>
/// <param name="distance">到直线的距离</param>
/// <param name="relativeFristPoint">所求点是对应直线两点的哪一个:true-对应linePoint[0]点;false-对应linePoint[1]点</param>
/// <returns>到直线上特定点固定距离的两个点数组</returns>
private Point[] GetPointsOfDistanceToPointOnTheLine(Point[] linePoint, double distance, bool relativeFristPoint = true)
{
Point[] points = new Point[2];
Point relativePoint = relativeFristPoint ? linePoint[0] : linePoint[1];
if (linePoint.Length != 2)
throw new AggregateException("参数个数不正确");
if (linePoint[0].Equals(linePoint[1]) && Math.Abs(distance) < 0.1)
throw new ArgumentException("参数不正确");
if (linePoint[0].X.Equals(linePoint[1].X)) //垂直直线
{
points[0] = new Point(relativePoint.X - distance, relativePoint.Y);
points[1] = new Point(relativePoint.X + distance, relativePoint.Y);
}
else if (linePoint[0].Y.Equals(linePoint[1].Y)) //水平直线
{
points[0] = new Point(relativePoint.X, relativePoint.Y + distance);
points[1] = new Point(relativePoint.X, relativePoint.Y - distance);
}
else
{
double differenceY = linePoint[1].Y - linePoint[0].Y;
double differenceX = linePoint[1].X - linePoint[0].X;
double centerValue = Math.Sqrt(Math.Pow(distance, 2) - (1 + Math.Pow(differenceY / differenceX, 2)));
double getX1 = relativePoint.X + centerValue;
double getY1 = differenceX * (relativePoint.X - getX1) / differenceY + relativePoint.Y;
points[1] = new Point(getX1, getY1);
double getX2 = relativePoint.X - centerValue;
double getY2 = differenceX * (relativePoint.X - getX2) / differenceY + relativePoint.Y;
points[0] = new Point(getX2, getY2);
}
return points;
}
/// <summary>
/// 求两条线的交点
/// </summary>
/// <param name="point">前两个点与后两个点分别确定两条直线</param>
/// <returns>两直线焦点</returns>
private Point GetIntersectionyOfTwoLines(Point[] point)
{
Point intersectiony = new Point();
if (point.Length != 4)
throw new AggregateException("参数个数不正确");
if (point[0].Equals(point[1]) && point[2].Equals(point[4]))
throw new ArgumentException("参数相同");
bool line1IsVertical, line2IsVertical;
line1IsVertical = point[1].X.Equals(point[0].X);
line2IsVertical = point[3].X.Equals(point[2].X);
if (line1IsVertical || line2IsVertical) //两条直线存在垂直的情况
{
if (line1IsVertical && line2IsVertical)
{
throw new ArgumentException("两直线平行,无交点");
}
else
{
if (line1IsVertical)
{
intersectiony.X = point[0].X;
double differenceX = point[3].X - point[2].X;
double differenceY = point[3].Y - point[2].Y;
intersectiony.Y = differenceY * (intersectiony.X - point[2].X) / differenceX + point[2].Y;
}
else
{
intersectiony.X = point[2].X;
double differenceX = point[1].X - point[0].X;
double differenceY = point[1].Y - point[0].Y;
intersectiony.Y = differenceY * (intersectiony.X - point[0].X) / differenceX + point[0].Y;
}
}
}
else
{
double differenceX1 = point[1].X - point[0].X;
double differenceX2 = point[3].X - point[2].X;
double differenceY1 = point[1].Y - point[0].Y;
double differenceY2 = point[3].Y - point[2].Y;
if ((differenceY1 * differenceX2).Equals(differenceY2 * differenceX1))
{
throw new ArgumentException("两直线平行,无交点");
}
else
{
intersectiony.X = (point[0].Y - point[2].Y + differenceY2 * point[2].X / differenceX2 - differenceY1 * point[0].X / differenceX1) /
(differenceY2 / differenceX2 - differenceY1 / differenceX1);
intersectiony.Y = differenceY1 * (intersectiony.X - point[0].X) / differenceX1 + point[0].Y;
}
}
return intersectiony;
}