优化圆弧段渲染,使用完整车辆长方体替代多段长方体,提升可视化效果
This commit is contained in:
parent
1370ce1fd2
commit
c0333810ec
@ -2725,91 +2725,8 @@ namespace NavisworksTransport
|
||||
lineMarker.SampledPoints != null &&
|
||||
lineMarker.SampledPoints.Count >= 2)
|
||||
{
|
||||
// 圆弧段:多段长方体拼接
|
||||
// 为了避免外侧出现缝隙,需要根据外侧弧线长度调整每个长方体的长度(厚度)
|
||||
|
||||
// 计算外侧弧线长度 = (圆弧半径 + 宽度/2) * 偏转角
|
||||
// 注意:宽度是长方体的总宽度,所以半径是 width/2
|
||||
double outerArcRadius = width / 2.0; // 长方体的半径(宽度的一半)
|
||||
double outerArcLength = 0;
|
||||
double centerArcRadius = 0;
|
||||
|
||||
if (lineMarker.Trajectory != null)
|
||||
{
|
||||
centerArcRadius = lineMarker.Trajectory.ActualRadius;
|
||||
outerArcLength = (centerArcRadius + outerArcRadius) * lineMarker.Trajectory.DeflectionAngle;
|
||||
}
|
||||
|
||||
// 计算每个长方体在外侧应该覆盖的长度
|
||||
int segmentCount = lineMarker.SampledPoints.Count - 1;
|
||||
double outerSegmentLength = outerArcLength / segmentCount;
|
||||
|
||||
// 提前计算比例因子,避免在循环中重复计算
|
||||
double lengthScaleFactor = (centerArcRadius + outerArcRadius) / centerArcRadius;
|
||||
|
||||
// 设置颜色和透明度
|
||||
graphics.Color(lineMarker.Color, lineMarker.Opacity);
|
||||
|
||||
// 添加过渡切片(在第一个切片前)
|
||||
// 从第一个切片反向画一个切片,填补外侧缝隙
|
||||
// 计算第一个切片的方向(从 SampledPoints[0] 到 SampledPoints[1])
|
||||
var firstSliceDirection = new Vector3D(
|
||||
lineMarker.SampledPoints[1].X - lineMarker.SampledPoints[0].X,
|
||||
lineMarker.SampledPoints[1].Y - lineMarker.SampledPoints[0].Y,
|
||||
lineMarker.SampledPoints[1].Z - lineMarker.SampledPoints[0].Z
|
||||
);
|
||||
var firstSliceLength = Math.Sqrt(
|
||||
firstSliceDirection.X * firstSliceDirection.X +
|
||||
firstSliceDirection.Y * firstSliceDirection.Y +
|
||||
firstSliceDirection.Z * firstSliceDirection.Z
|
||||
);
|
||||
|
||||
firstSliceDirection = new Vector3D(
|
||||
firstSliceDirection.X / firstSliceLength,
|
||||
firstSliceDirection.Y / firstSliceLength,
|
||||
firstSliceDirection.Z / firstSliceLength
|
||||
);
|
||||
|
||||
// 反向切片:从 SampledPoints[0] 沿第一个切片的反方向延伸
|
||||
// 使用完整的 outerSegmentLength 作为长度
|
||||
var reverseSliceEndPoint = new Point3D(
|
||||
lineMarker.SampledPoints[0].X - firstSliceDirection.X * outerSegmentLength,
|
||||
lineMarker.SampledPoints[0].Y - firstSliceDirection.Y * outerSegmentLength,
|
||||
lineMarker.SampledPoints[0].Z - firstSliceDirection.Z * outerSegmentLength
|
||||
);
|
||||
|
||||
RenderCuboidMarkerWithLength(
|
||||
graphics,
|
||||
reverseSliceEndPoint,
|
||||
lineMarker.SampledPoints[0],
|
||||
width,
|
||||
lineMarker.Height,
|
||||
outerSegmentLength,
|
||||
lineMarker.HorizontalDirection
|
||||
);
|
||||
|
||||
for (int i = 0; i < lineMarker.SampledPoints.Count - 1; i++)
|
||||
{
|
||||
// 计算当前段的中心线长度
|
||||
double centerSegmentLength = GeometryHelper.CalculatePointDistance(
|
||||
lineMarker.SampledPoints[i],
|
||||
lineMarker.SampledPoints[i + 1]
|
||||
);
|
||||
|
||||
// 计算长方体应该使用的长度(基于外侧弧线)
|
||||
double cuboidLength = centerSegmentLength * lengthScaleFactor;
|
||||
|
||||
// 渲染长方体,使用调整后的长度
|
||||
RenderCuboidMarkerWithLength(
|
||||
graphics,
|
||||
lineMarker.SampledPoints[i],
|
||||
lineMarker.SampledPoints[i + 1],
|
||||
width,
|
||||
lineMarker.Height,
|
||||
cuboidLength,
|
||||
lineMarker.HorizontalDirection
|
||||
);
|
||||
}
|
||||
// 圆弧段:在每个采样点渲染完整的车辆长方体
|
||||
RenderArcSegmentCuboids(graphics, lineMarker, width);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2827,6 +2744,103 @@ namespace NavisworksTransport
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 渲染圆弧段的车辆长方体
|
||||
/// 在每个采样点处渲染一个完整的车辆长方体,中心在采样点,向前后各延伸 L/2
|
||||
/// </summary>
|
||||
/// <param name="graphics">图形上下文</param>
|
||||
/// <param name="lineMarker">连线标记(必须是圆弧段)</param>
|
||||
/// <param name="width">长方体宽度</param>
|
||||
private void RenderArcSegmentCuboids(Graphics graphics, LineMarker lineMarker, double width)
|
||||
{
|
||||
// 设置颜色和透明度
|
||||
graphics.Color(lineMarker.Color, lineMarker.Opacity);
|
||||
|
||||
// 在每个采样点处渲染完整的车辆长方体
|
||||
for (int i = 0; i < lineMarker.SampledPoints.Count; i++)
|
||||
{
|
||||
// 计算当前采样点的切线方向
|
||||
Vector3D tangent = CalculateTangentAtSamplePoint(lineMarker.SampledPoints, i);
|
||||
|
||||
// 计算长方体的起点和终点(沿切线方向,各延伸 L/2)
|
||||
var halfLength = _passageAlongPath / 2.0;
|
||||
var startPoint = new Point3D(
|
||||
lineMarker.SampledPoints[i].X - tangent.X * halfLength,
|
||||
lineMarker.SampledPoints[i].Y - tangent.Y * halfLength,
|
||||
lineMarker.SampledPoints[i].Z - tangent.Z * halfLength
|
||||
);
|
||||
var endPoint = new Point3D(
|
||||
lineMarker.SampledPoints[i].X + tangent.X * halfLength,
|
||||
lineMarker.SampledPoints[i].Y + tangent.Y * halfLength,
|
||||
lineMarker.SampledPoints[i].Z + tangent.Z * halfLength
|
||||
);
|
||||
|
||||
RenderCuboidMarkerWithLength(
|
||||
graphics,
|
||||
startPoint,
|
||||
endPoint,
|
||||
width,
|
||||
lineMarker.Height,
|
||||
_passageAlongPath,
|
||||
lineMarker.HorizontalDirection
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算采样点处的切线方向
|
||||
/// </summary>
|
||||
/// <param name="sampledPoints">采样点列表</param>
|
||||
/// <param name="index">当前采样点索引</param>
|
||||
/// <returns>归一化的切线向量</returns>
|
||||
private Vector3D CalculateTangentAtSamplePoint(List<Point3D> sampledPoints, int index)
|
||||
{
|
||||
Vector3D tangent;
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
// 第一个点:使用到下一点的向量作为切线
|
||||
tangent = new Vector3D(
|
||||
sampledPoints[1].X - sampledPoints[0].X,
|
||||
sampledPoints[1].Y - sampledPoints[0].Y,
|
||||
sampledPoints[1].Z - sampledPoints[0].Z
|
||||
);
|
||||
}
|
||||
else if (index == sampledPoints.Count - 1)
|
||||
{
|
||||
// 最后一个点:使用从上一点到当前点的向量作为切线
|
||||
tangent = new Vector3D(
|
||||
sampledPoints[index].X - sampledPoints[index - 1].X,
|
||||
sampledPoints[index].Y - sampledPoints[index - 1].Y,
|
||||
sampledPoints[index].Z - sampledPoints[index - 1].Z
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 中间点:使用前后两点的平均方向作为切线
|
||||
var prev = new Vector3D(
|
||||
sampledPoints[index].X - sampledPoints[index - 1].X,
|
||||
sampledPoints[index].Y - sampledPoints[index - 1].Y,
|
||||
sampledPoints[index].Z - sampledPoints[index - 1].Z
|
||||
);
|
||||
var next = new Vector3D(
|
||||
sampledPoints[index + 1].X - sampledPoints[index].X,
|
||||
sampledPoints[index + 1].Y - sampledPoints[index].Y,
|
||||
sampledPoints[index + 1].Z - sampledPoints[index].Z
|
||||
);
|
||||
tangent = new Vector3D(prev.X + next.X, prev.Y + next.Y, prev.Z + next.Z);
|
||||
}
|
||||
|
||||
// 归一化切线向量
|
||||
var tangentLength = Math.Sqrt(tangent.X * tangent.X + tangent.Y * tangent.Y + tangent.Z * tangent.Z);
|
||||
if (tangentLength > 0.001)
|
||||
{
|
||||
tangent = new Vector3D(tangent.X / tangentLength, tangent.Y / tangentLength, tangent.Z / tangentLength);
|
||||
}
|
||||
|
||||
return tangent;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 渲染点标记
|
||||
|
||||
Loading…
Reference in New Issue
Block a user