|
|
|
@ -75,11 +75,11 @@ public class ViewportHelperPro |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
var mesh = meshBuilder.ToMeshGeometry3D(); |
|
|
|
|
|
|
|
|
|
color = new Color4(color ?? ViewportManager.ColorConfig.MainFacetColor); |
|
|
|
|
var material = new PBRMaterial |
|
|
|
|
{ |
|
|
|
|
AlbedoColor = new Color4(0.0f, 0f,0f,0.8f), // 黑色,避免其他光照影响 |
|
|
|
|
EmissiveColor =color ?? ViewportManager.ColorConfig.MainFacetColor , // LightGray #D3D3D3 |
|
|
|
|
AlbedoColor = new Color4(0.0f, 0f,0f,0.7f), // 黑色,避免其他光照影响 |
|
|
|
|
EmissiveColor =new Color4(color.Value.Red, color.Value.Green, color.Value.Blue, 0.7f) , // LightGray #D3D3D3 |
|
|
|
|
MetallicFactor = 0.0, // 非金属 |
|
|
|
|
RoughnessFactor = 1.0, // 高粗糙度,避免反射效果 |
|
|
|
|
ReflectanceFactor = 0.0, // 无反射 |
|
|
|
@ -123,6 +123,8 @@ public class ViewportHelperPro |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static Color4? GenFaceColor4(PlaneType planeType) |
|
|
|
|
{ |
|
|
|
|
switch (planeType) |
|
|
|
@ -304,6 +306,73 @@ public class ViewportHelperPro |
|
|
|
|
}).ConfigureAwait(false); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static List<LineGeometryModel3D> ShowCenterTag(float lineLength = 0.5f) |
|
|
|
|
{ |
|
|
|
|
List<LineGeometryModel3D> result = new List<LineGeometryModel3D>(); |
|
|
|
|
|
|
|
|
|
Vector3 boxCenter = ViewportManager.CenterVector; |
|
|
|
|
//中心 22 |
|
|
|
|
Tuple<Vector3, Vector3> centerLineX = new Tuple<Vector3, Vector3>( |
|
|
|
|
new Vector3(boxCenter.X - lineLength, boxCenter.Y, boxCenter.Z), |
|
|
|
|
new Vector3(boxCenter.X + lineLength, boxCenter.Y, boxCenter.Z)); |
|
|
|
|
Tuple<Vector3, Vector3> centerLineZ = new Tuple<Vector3, Vector3>( |
|
|
|
|
new Vector3(boxCenter.X, boxCenter.Y, boxCenter.Z - lineLength), |
|
|
|
|
new Vector3(boxCenter.X, boxCenter.Y, boxCenter.Z + lineLength)); |
|
|
|
|
//中心 台 |
|
|
|
|
List<Vector3> tablePoints = new List<Vector3>(); |
|
|
|
|
foreach (var entity in ViewportManager.ViewportTriangle.Where(entity => entity.PlaneType == PlaneType.TableFacet).ToList()) |
|
|
|
|
{ |
|
|
|
|
tablePoints.Add(entity.Point1); |
|
|
|
|
tablePoints.Add(entity.Point2); |
|
|
|
|
tablePoints.Add(entity.Point3); |
|
|
|
|
} |
|
|
|
|
HashSet<Vector3> tablePointSet = new HashSet<Vector3>(tablePoints); |
|
|
|
|
tablePoints = VectorClockwiseSort(tablePointSet.ToList()); |
|
|
|
|
|
|
|
|
|
List<Tuple<Vector3, Vector3>> line = new List<Tuple<Vector3, Vector3>>(); |
|
|
|
|
for (int i = 0; i < tablePoints.Count / 2; i++) |
|
|
|
|
{ |
|
|
|
|
line.Add(new Tuple<Vector3, Vector3>(tablePoints[i], tablePoints[i+tablePoints.Count / 2])); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vector3 tableCenter = CalculateIntersection(line.Last(), line.First()) ?? GetCentroid(tablePointSet.ToList()); |
|
|
|
|
Tuple<Vector3, Vector3> tableLineX = new Tuple<Vector3, Vector3>( |
|
|
|
|
new Vector3(tableCenter.X - lineLength, tableCenter.Y, tableCenter.Z), |
|
|
|
|
new Vector3(tableCenter.X + lineLength, tableCenter.Y, tableCenter.Z)); |
|
|
|
|
Tuple<Vector3, Vector3> tableLineZ = new Tuple<Vector3, Vector3>( |
|
|
|
|
new Vector3(tableCenter.X, tableCenter.Y, tableCenter.Z - lineLength), |
|
|
|
|
new Vector3(tableCenter.X, tableCenter.Y, tableCenter.Z + lineLength)); |
|
|
|
|
//中心 底尖 |
|
|
|
|
List<Vector3> culetPoints = new List<Vector3>(); |
|
|
|
|
foreach (var entity in ViewportManager.ViewportTriangle.Where(entity => entity.PlaneType == PlaneType.Culet).ToList()) |
|
|
|
|
{ |
|
|
|
|
culetPoints.Add(entity.Point1); |
|
|
|
|
culetPoints.Add(entity.Point2); |
|
|
|
|
culetPoints.Add(entity.Point3); |
|
|
|
|
} |
|
|
|
|
Vector3 culetCenter = GetCentroid(culetPoints); |
|
|
|
|
Tuple<Vector3, Vector3> culetLineX = new Tuple<Vector3, Vector3>( |
|
|
|
|
new Vector3(culetCenter.X - lineLength, culetCenter.Y, culetCenter.Z), |
|
|
|
|
new Vector3(culetCenter.X + lineLength, culetCenter.Y, culetCenter.Z)); |
|
|
|
|
Tuple<Vector3, Vector3> culetLineZ = new Tuple<Vector3, Vector3>( |
|
|
|
|
new Vector3(culetCenter.X, culetCenter.Y, culetCenter.Z - lineLength), |
|
|
|
|
new Vector3(culetCenter.X, culetCenter.Y, culetCenter.Z + lineLength)); |
|
|
|
|
|
|
|
|
|
List<Tuple<Vector3, Vector3>> centerLines = new List<Tuple<Vector3, Vector3>> |
|
|
|
|
{ centerLineX, centerLineZ}; |
|
|
|
|
List<Tuple<Vector3, Vector3>> tableLines = new List<Tuple<Vector3, Vector3>> |
|
|
|
|
{ tableLineX, tableLineZ }; |
|
|
|
|
List<Tuple<Vector3, Vector3>> culetLines = new List<Tuple<Vector3, Vector3>> |
|
|
|
|
{ culetLineZ, culetLineX }; |
|
|
|
|
|
|
|
|
|
result.Add(DisplayLineModel3D(centerLines, Color.Red, 0.8f)); |
|
|
|
|
result.Add(DisplayLineModel3D(tableLines, Color.Green, 1f)); |
|
|
|
|
result.Add(DisplayLineModel3D(culetLines, Color.Blue, 0.8f)); |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
|
/// 通过三角形实体集合生成每个面的边框线 |
|
|
|
|
/// </summary> |
|
|
|
@ -316,6 +385,7 @@ public class ViewportHelperPro |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
|
/// 通过三角形实体集合生成每个面的边框线(只生成不添加) |
|
|
|
|
/// </summary> |
|
|
|
@ -520,91 +590,153 @@ public class ViewportHelperPro |
|
|
|
|
var result = new List<GeometryModel3D>(); |
|
|
|
|
if (selFacetType == PlaneType.Girdle && string.IsNullOrWhiteSpace(valKey)) |
|
|
|
|
{ |
|
|
|
|
Logger.Info($"【面文本生成】 命中面{selFacetType},是腰"); |
|
|
|
|
// Logger.Info($"【面文本生成】 命中面{selFacetType},是腰"); |
|
|
|
|
// List<Viewport3DTriangleEntity> facetTypeAll = |
|
|
|
|
// ViewportManager.ViewportTriangle.FindAll(e => e.PlaneType == selFacetType); |
|
|
|
|
// var groupedDic = facetTypeAll.GroupBy(entity => entity.PlaneCode) |
|
|
|
|
// .ToDictionary(group => group.Key, group => group.ToList()); |
|
|
|
|
// Logger.Info($"【面文本生成】 腰由{groupedDic.Count}个面组成"); |
|
|
|
|
// |
|
|
|
|
// var selPlaneCode = entities.First().PlaneCode; |
|
|
|
|
// Logger.Info($"【面文本生成】 当前选择{selPlaneCode}"); |
|
|
|
|
// |
|
|
|
|
// List<Vector3> facetPoints = new List<Vector3>(); |
|
|
|
|
// entities.ForEach(e => { facetPoints.Add(e.Point1); facetPoints.Add(e.Point2); facetPoints.Add(e.Point3); }); |
|
|
|
|
// var facetIndex = -1; |
|
|
|
|
// int.TryParse(selPlaneCode.Split("_")[1], out facetIndex); |
|
|
|
|
// |
|
|
|
|
// if (facetIndex == -1) |
|
|
|
|
// { |
|
|
|
|
// Logger.Info($"【面文本生成】 面索引解析失败{selPlaneCode}"); |
|
|
|
|
// return result; |
|
|
|
|
// } |
|
|
|
|
// int linePointType = facetIndex % 4; |
|
|
|
|
// Console.WriteLine(facetIndex); |
|
|
|
|
// switch (linePointType) |
|
|
|
|
// { |
|
|
|
|
// case 0: |
|
|
|
|
// case 2: |
|
|
|
|
// var longestLine1 = GetLeftOrRightLineSegment(facetPoints, facetIndex >= 25 && facetIndex <= 57 ? true : false); |
|
|
|
|
// result.Add(DisplayLineModel3D(new List<Tuple<Vector3, Vector3>>() { longestLine1 }, new Color4(1f, 0, 0, 1f), 2f)); |
|
|
|
|
// break; |
|
|
|
|
// case 1: |
|
|
|
|
// case 3: |
|
|
|
|
// var longestLine2 = GetLeftOrRightLineSegment(facetPoints, facetIndex >= 25 && facetIndex <= 57 ? false : true); |
|
|
|
|
// result.Add(DisplayLineModel3D(new List<Tuple<Vector3, Vector3>>() { longestLine2 }, new Color4(1f, 0, 0, 1f), 2f)); |
|
|
|
|
// break; |
|
|
|
|
// } |
|
|
|
|
// |
|
|
|
|
// if (result.Exists(e => e == null)) |
|
|
|
|
// { |
|
|
|
|
// Logger.Info("目标线段为空"); |
|
|
|
|
// return result; |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
//开始找值[选中线的值] |
|
|
|
|
// string param = string.Empty; |
|
|
|
|
// var valueIndex = 0; |
|
|
|
|
// if (facetIndex % 8 == 0 || (facetIndex + 1) % 8 == 0) |
|
|
|
|
// { |
|
|
|
|
// //上腰面 |
|
|
|
|
// Logger.Info($"【面文本生成】 腰面值 波峰【上腰面】"); |
|
|
|
|
// valueIndex = (int)Math.Ceiling(facetIndex / 8.0) == 8 ? 0 : (int)Math.Ceiling(facetIndex / 8.0); |
|
|
|
|
// param = "GIRDLE_BONE"; |
|
|
|
|
// } else if (linePointType == 3 || linePointType == 0) |
|
|
|
|
// { |
|
|
|
|
// //风筝面 |
|
|
|
|
// Logger.Info($"【面文本生成】 腰面值 波峰【风筝面】"); |
|
|
|
|
// valueIndex = (facetIndex / 8); |
|
|
|
|
// param = "GIRDLE_BEZEL"; |
|
|
|
|
// } |
|
|
|
|
// else |
|
|
|
|
// { |
|
|
|
|
// //腰厚比 |
|
|
|
|
// Logger.Info($"【面文本生成】 腰面值 波峰【腰厚比】"); |
|
|
|
|
// valueIndex = (facetIndex / 4); |
|
|
|
|
// param = "GIRDLE_VALLEY"; |
|
|
|
|
// } |
|
|
|
|
// |
|
|
|
|
// valueIndex += 1; |
|
|
|
|
// var detail = ViewportManager.DiamondData[$"{param}_DETAIL"]; |
|
|
|
|
// if (detail == null) |
|
|
|
|
// { |
|
|
|
|
// Logger.Info($"【面文本生成】 {param}_DETAIL Key不存在"); |
|
|
|
|
// return result; |
|
|
|
|
// } |
|
|
|
|
// Logger.Info($"【面文本生成】 {param}_DETAIL == {detail}"); |
|
|
|
|
// var paramValue = detail[$"{param}_{valueIndex}"]; |
|
|
|
|
// if (paramValue == null) |
|
|
|
|
// { |
|
|
|
|
// Logger.Info($"【面文本生成】 {param}_DETAIL.{param}_{valueIndex} Key不存在"); |
|
|
|
|
// return result; |
|
|
|
|
// } |
|
|
|
|
// Logger.Info($"【面文本生成】 {param}_DETAIL.{param}_{valueIndex} ==={paramValue}"); |
|
|
|
|
// var valueFloat = (Math.Floor(float.Parse(paramValue.ToString()) * 1000) / 10).ToString(); |
|
|
|
|
// Logger.Info($"【面文本生成】 {valueFloat} -- {valueIndex}"); |
|
|
|
|
// var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector); |
|
|
|
|
// result.Add(DisplayText3D($"{valueFloat}", facetTextPoint)); |
|
|
|
|
List<Viewport3DTriangleEntity> facetTypeAll = |
|
|
|
|
ViewportManager.ViewportTriangle.FindAll(e => e.PlaneType == selFacetType); |
|
|
|
|
var groupedDic = facetTypeAll.GroupBy(entity => entity.PlaneCode) |
|
|
|
|
.ToDictionary(group => group.Key, group => group.ToList()); |
|
|
|
|
Logger.Info($"【面文本生成】 腰由{groupedDic.Count}个面组成"); |
|
|
|
|
|
|
|
|
|
var selPlaneCode = entities.First().PlaneCode; |
|
|
|
|
Logger.Info($"【面文本生成】 当前选择{selPlaneCode}"); |
|
|
|
|
|
|
|
|
|
List<Vector3> facetPoints = new List<Vector3>(); |
|
|
|
|
entities.ForEach(e => { facetPoints.Add(e.Point1); facetPoints.Add(e.Point2); facetPoints.Add(e.Point3); }); |
|
|
|
|
var facetIndex = -1; |
|
|
|
|
int.TryParse(selPlaneCode.Split("_")[1], out facetIndex); |
|
|
|
|
|
|
|
|
|
if (facetIndex == -1) |
|
|
|
|
{ |
|
|
|
|
Logger.Info($"【面文本生成】 面索引解析失败{selPlaneCode}"); |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
int linePointType = facetIndex % 4; |
|
|
|
|
Console.WriteLine(facetIndex); |
|
|
|
|
switch (linePointType) |
|
|
|
|
{ |
|
|
|
|
case 0: |
|
|
|
|
case 2: |
|
|
|
|
var longestLine1 = GetLeftOrRightLineSegment(facetPoints, facetIndex >= 25 && facetIndex <= 57 ? true : false); |
|
|
|
|
result.Add(DisplayLineModel3D(new List<Tuple<Vector3, Vector3>>() { longestLine1 }, new Color4(1f, 0, 0, 1f), 2f)); |
|
|
|
|
break; |
|
|
|
|
case 1: |
|
|
|
|
case 3: |
|
|
|
|
var longestLine2 = GetLeftOrRightLineSegment(facetPoints, facetIndex >= 25 && facetIndex <= 57 ? false : true); |
|
|
|
|
result.Add(DisplayLineModel3D(new List<Tuple<Vector3, Vector3>>() { longestLine2 }, new Color4(1f, 0, 0, 1f), 2f)); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (result.Exists(e => e == null)) |
|
|
|
|
{ |
|
|
|
|
Logger.Info("目标线段为空"); |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//开始找值 |
|
|
|
|
string param = string.Empty; |
|
|
|
|
var valueIndex = 0; |
|
|
|
|
if (facetIndex % 8 == 0 || (facetIndex + 1) % 8 == 0) |
|
|
|
|
{ |
|
|
|
|
//上腰面 |
|
|
|
|
Logger.Info($"【面文本生成】 腰面值 波峰【上腰面】"); |
|
|
|
|
valueIndex = (int)Math.Ceiling(facetIndex / 8.0) == 8 ? 0 : (int)Math.Ceiling(facetIndex / 8.0); |
|
|
|
|
param = "GIRDLE_BONE"; |
|
|
|
|
} else if (linePointType == 3 || linePointType == 0) |
|
|
|
|
{ |
|
|
|
|
//风筝面 |
|
|
|
|
Logger.Info($"【面文本生成】 腰面值 波峰【风筝面】"); |
|
|
|
|
valueIndex = (facetIndex / 8); |
|
|
|
|
param = "GIRDLE_BEZEL"; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
List<string> girdleKey = new List<string> { "GIRDLE_BEZEL", "GIRDLE_BONE", "GIRDLE_VALLEY" }; |
|
|
|
|
var girdleResultDic = new Dictionary<string, Dictionary<string, List<Viewport3DTriangleEntity>>>(); |
|
|
|
|
foreach (var key in girdleKey) |
|
|
|
|
{ |
|
|
|
|
//腰厚比 |
|
|
|
|
Logger.Info($"【面文本生成】 腰面值 波峰【腰厚比】"); |
|
|
|
|
valueIndex = (facetIndex / 4); |
|
|
|
|
param = "GIRDLE_VALLEY"; |
|
|
|
|
var resultDic = new Dictionary<string, List<Viewport3DTriangleEntity>>(); |
|
|
|
|
for (int i = 0; i < groupedDic.Count; i++) |
|
|
|
|
{ |
|
|
|
|
switch (key) |
|
|
|
|
{ |
|
|
|
|
case "GIRDLE_BEZEL": if (i % 8 == 4) resultDic.Add($"0_{i}", groupedDic[$"0_{i}"]); |
|
|
|
|
break; |
|
|
|
|
case "GIRDLE_BONE": if (i % 8 == 0) resultDic.Add($"0_{i}", groupedDic[$"0_{i}"]); |
|
|
|
|
break; |
|
|
|
|
case "GIRDLE_VALLEY": if (i % 4 == 2) resultDic.Add($"0_{i}", groupedDic[$"0_{i}"]); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
girdleResultDic.Add(key, resultDic); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
valueIndex += 1; |
|
|
|
|
var detail = ViewportManager.DiamondData[$"{param}_DETAIL"]; |
|
|
|
|
if (detail == null) |
|
|
|
|
foreach (var gridleResult in girdleResultDic) |
|
|
|
|
{ |
|
|
|
|
Logger.Info($"【面文本生成】 {param}_DETAIL Key不存在"); |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
Logger.Info($"【面文本生成】 {param}_DETAIL == {detail}"); |
|
|
|
|
var paramValue = detail[$"{param}_{valueIndex}"]; |
|
|
|
|
if (paramValue == null) |
|
|
|
|
{ |
|
|
|
|
Logger.Info($"【面文本生成】 {param}_DETAIL.{param}_{valueIndex} Key不存在"); |
|
|
|
|
return result; |
|
|
|
|
foreach (var dic in gridleResult.Value) |
|
|
|
|
{ |
|
|
|
|
//高亮四边形左边的线,并绑定值 |
|
|
|
|
List<Vector3> facetPoints = new List<Vector3>(); |
|
|
|
|
dic.Value.ForEach(e => { facetPoints.Add(e.Point1); facetPoints.Add(e.Point2); facetPoints.Add(e.Point3); }); |
|
|
|
|
//高亮的线 |
|
|
|
|
var facetIndex = int.Parse(dic.Key.Split("_")[1]) - 1; |
|
|
|
|
if ("GIRDLE_VALLEY".Equals(gridleResult.Key)) |
|
|
|
|
{ |
|
|
|
|
var showLine =GetLeftOrRightLineSegment(facetPoints, facetIndex >= 25 && facetIndex <= 57 ? true : false);; |
|
|
|
|
if (showLine == null) continue; |
|
|
|
|
result.Add(DisplayLineModel3D(new List<Tuple<Vector3, Vector3>>() { showLine }, new Color4(1f, 0, 0, 1f), 2f)); |
|
|
|
|
} |
|
|
|
|
//文字显示位置 |
|
|
|
|
var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector); |
|
|
|
|
var resIndex = gridleResult.Value.Keys.ToList().IndexOf(dic.Key); |
|
|
|
|
if (resIndex == -1) continue; |
|
|
|
|
resIndex += 1; |
|
|
|
|
var detail = ViewportManager.DiamondData[$"{gridleResult.Key}_DETAIL"]; |
|
|
|
|
if (detail == null) |
|
|
|
|
{ |
|
|
|
|
Logger.Info($"【面文本生成】 {gridleResult.Key}_DETAIL Key不存在"); |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
Logger.Info($"【面文本生成】 {gridleResult.Key}_DETAIL == {detail}"); |
|
|
|
|
var paramValue = detail[$"{gridleResult.Key}_{resIndex}"]; |
|
|
|
|
if (paramValue == null) |
|
|
|
|
{ |
|
|
|
|
Logger.Info($"【面文本生成】 {gridleResult.Key}_DETAIL.{gridleResult.Key}_{resIndex} Key不存在"); |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var valueFloat = ValueFormat(paramValue.ToString(), gridleResult.Key, false); |
|
|
|
|
result.Add(DisplayText3D($"{valueFloat}", facetTextPoint)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
Logger.Info($"【面文本生成】 {param}_DETAIL.{param}_{valueIndex} ==={paramValue}"); |
|
|
|
|
var valueFloat = (Math.Floor(float.Parse(paramValue.ToString()) * 1000) / 10).ToString(); |
|
|
|
|
Logger.Info($"【面文本生成】 {valueFloat} -- {valueIndex}"); |
|
|
|
|
var facetTextPoint = GetOffsetCenter(facetPoints, ViewportManager.CenterVector); |
|
|
|
|
result.Add(DisplayText3D($"{valueFloat}", facetTextPoint)); |
|
|
|
|
|
|
|
|
|
} else if (selFacetType == PlaneType.Girdle && !string.IsNullOrWhiteSpace(valKey)) |
|
|
|
|
{ |
|
|
|
@ -1329,7 +1461,7 @@ public class ViewportHelperPro |
|
|
|
|
/// <param name="entities"></param> |
|
|
|
|
/// <param name="thickness"></param> |
|
|
|
|
/// <returns></returns> |
|
|
|
|
public static List<LineGeometryModel3D> ShowMeshLines(bool isCrown = true, double thickness = 0.2) |
|
|
|
|
public static List<LineGeometryModel3D> ShowMeshLines(bool isCrown = true, double thickness = 0.5) |
|
|
|
|
{ |
|
|
|
|
List<LineGeometryModel3D> lines = new(); |
|
|
|
|
var Y = -0.01F; |
|
|
|
@ -1668,7 +1800,7 @@ public class ViewportHelperPro |
|
|
|
|
/// <param name="radius"></param> |
|
|
|
|
/// <param name="thickness"></param> |
|
|
|
|
/// <returns></returns> |
|
|
|
|
public static LineGeometryModel3D ShowCircleLine(bool isCrown = true, double radius = 1.0, double thickness = 0.2) |
|
|
|
|
public static LineGeometryModel3D ShowCircleLine(bool isCrown = true, double radius = 1.0, double thickness = 0.5) |
|
|
|
|
{ |
|
|
|
|
var Y = -0.01F; |
|
|
|
|
if (!isCrown) |
|
|
|
@ -2085,6 +2217,47 @@ public class ViewportHelperPro |
|
|
|
|
return "--"; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static Vector3? CalculateIntersection( |
|
|
|
|
Tuple<Vector3, Vector3> line1, |
|
|
|
|
Tuple<Vector3, Vector3> line2) |
|
|
|
|
{ |
|
|
|
|
// 提取线段端点 |
|
|
|
|
Vector3 a1 = line1.Item1, a2 = line1.Item2; |
|
|
|
|
Vector3 b1 = line2.Item1, b2 = line2.Item2; |
|
|
|
|
|
|
|
|
|
// 投影到XZ平面(忽略Y轴) |
|
|
|
|
float dx1 = a2.X - a1.X; |
|
|
|
|
float dz1 = a2.Z - a1.Z; |
|
|
|
|
float dx2 = b2.X - b1.X; |
|
|
|
|
float dz2 = b2.Z - b1.Z; |
|
|
|
|
|
|
|
|
|
// 计算分母 |
|
|
|
|
float denominator = dx1 * dz2 - dx2 * dz1; |
|
|
|
|
|
|
|
|
|
// 检查平行或共线 |
|
|
|
|
if (Math.Abs(denominator) < float.Epsilon) |
|
|
|
|
return null; // 无唯一交点 |
|
|
|
|
|
|
|
|
|
// 计算参数t和s |
|
|
|
|
float t = ((b1.X - a1.X) * dz2 - (b1.Z - a1.Z) * dx2) / denominator; |
|
|
|
|
float s = ((a1.X - b1.X) * dz1 - (a1.Z - b1.Z) * dx1) / -denominator; |
|
|
|
|
|
|
|
|
|
// 检查交点是否在线段范围内 |
|
|
|
|
if (t < 0 || t > 1 || s < 0 || s > 1) |
|
|
|
|
return null; // 线段不相交 |
|
|
|
|
|
|
|
|
|
// 计算交点坐标(XZ平面) |
|
|
|
|
float x = a1.X + dx1 * t; |
|
|
|
|
float z = a1.Z + dz1 * t; |
|
|
|
|
|
|
|
|
|
// 计算最大Y值 |
|
|
|
|
float maxY = Math.Max( |
|
|
|
|
Math.Max(a1.Y, a2.Y), |
|
|
|
|
Math.Max(b1.Y, b2.Y) |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
return new Vector3(x, maxY, z); |
|
|
|
|
} |
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|