diff --git a/Views/UserControl/Viewport3D.xaml.cs b/Views/UserControl/Viewport3D.xaml.cs index 74a0429..3e6dc03 100644 --- a/Views/UserControl/Viewport3D.xaml.cs +++ b/Views/UserControl/Viewport3D.xaml.cs @@ -413,12 +413,14 @@ public partial class Viewport3D ViewportManager.ResetChooseAddModels(); break; case "ViewportRightMenuShowMeshLines": + var center = ViewportManager.ModelBounds.Center; var maxDimension = ViewportManager.ModelBounds.Size.Length(); var distance = maxDimension * 1.2; // 调整相机到模型的距离,保证视野范围内 - var center = ViewportManager.ModelBounds.Center; + // 获取当前相机 var camera = Viewport3Dx.Camera as HelixToolkit.Wpf.SharpDX.PerspectiveCamera; camera.Position = new Point3D(center.X, center.Y - distance, center.Z); // 从底部看,Y轴负方向 camera.UpDirection = new Vector3D(0, 0, -1); + camera.LookDirection = new Vector3D(center.X - camera.Position.X, center.Y - camera.Position.Y, center.Z - camera.Position.Z); ViewportManager.ShowMeshLines(checkResult); //camera.LookDirection = new Vector3D(center.X - camera.Position.X, center.Y - camera.Position.Y, center.Z - camera.Position.Z); diff --git a/Views/UserControl/ViewportData/Helper/LineCalculationHelper.cs b/Views/UserControl/ViewportData/Helper/LineCalculationHelper.cs index cdc7622..7789ba1 100644 --- a/Views/UserControl/ViewportData/Helper/LineCalculationHelper.cs +++ b/Views/UserControl/ViewportData/Helper/LineCalculationHelper.cs @@ -12,7 +12,7 @@ namespace SparkClient.Views.UserControl.ViewportData.Helper { private readonly float Y = -0.01F; private Vector3 point1; - private Vector3 point2; + private Vector3 center; /// /// 常数a(y=ax+b) /// @@ -21,21 +21,21 @@ namespace SparkClient.Views.UserControl.ViewportData.Helper /// 常数b(y=ax+b) /// private float b; - public LineCalculationHelper(Vector3 point1, Vector3 point2) { + public LineCalculationHelper(Vector3 point1, Vector3 center) { this.point1 = point1; - this.point2 = point2; - this.a = calA(point1, point2); + this.center = center; + this.a = calA(point1, center); this.b = calB(point1, a); } /// /// 常数a的计算 /// /// - /// + /// /// - private float calA(Vector3 point1, Vector3 point2) + private float calA(Vector3 point1, Vector3 center) { - return (point1.Z - point2.Z) / (point1.X - point2.X); + return (point1.Z - center.Z) / (point1.X - center.X); } /// /// 常数b的计算 @@ -50,18 +50,20 @@ namespace SparkClient.Views.UserControl.ViewportData.Helper public Tuple calXline(float length) { - var x1 = 5; - var z1 = calZ(x1); - var x2 = -5; - var z2 = calZ(x2); + var twoPoint = CalculatePointsOnLine(this.a,length); + var x1 = twoPoint.p1.X; + var z1 = twoPoint.p1.Y; + var x2 = twoPoint.p2.X; + var z2 = twoPoint.p2.X; return new Tuple(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)); } public Tuple calYline(float length) { - var x1 = 5; - var z1 = calZVertical(x1); - var x2 = -5; - var z2 = calZVertical(x2); + var twoPoint = CalculatePointsOnLine(-(1/a), length); + var x1 = twoPoint.p1.X; + var z1 = twoPoint.p1.Y; + var x2 = twoPoint.p2.X; + var z2 = twoPoint.p2.X; return new Tuple(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)); } @@ -95,5 +97,33 @@ namespace SparkClient.Views.UserControl.ViewportData.Helper { return (-x / a) + b + offset; } + + private ((float X, float Y) p1, (float X, float Y) p2) CalculatePointsOnLine(float k ,float L) + { + float x0 = center.X; + float y0 = center.Z; + // 将距离公式展开并整理为关于 t 的二次方程 + float A = 1 + k * k; + float B = -2 * x0 + 2 * k * (b - y0); + float C = x0 * x0 + (b - y0) * (b - y0) - L * L; + + // 计算判别式 + float discriminant = B * B - 4 * A * C; + + if (discriminant < 0) + { + throw new InvalidOperationException("无解:距离 L 太小,无法找到满足条件的点。"); + } + + // 计算 t 的两个解 + float t1 = (float)(-B + Math.Sqrt(discriminant)) / (2 * A); + float t2 = (float)(-B - Math.Sqrt(discriminant)) / (2 * A); + + // 计算两点坐标 + var p1 = (X: t1, Y: k * t1 + b); + var p2 = (X: t2, Y: k * t2 + b); + + return (p1, p2); + } } } diff --git a/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs b/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs index a7db89b..48d063d 100644 --- a/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs +++ b/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs @@ -1273,6 +1273,12 @@ public class ViewportHelperPro lights.ForEach(item => viewport.Items.Remove(item)); } private static Dictionary moveLines = new Dictionary(); + /// + /// 网状参考线 + /// + /// + /// + /// public static List ShowMeshLines(List entities, double thickness = 1.0) { moveLines = new(); @@ -1288,9 +1294,14 @@ public class ViewportHelperPro var edgeLines = new List>(); Color4 XlineColor =new Color4(80f, 0f, 0f, 1f); - var x1 = 5; + float r =5; + if(double.TryParse(ViewportManager.DiamondData["M2"].ToString(), out var v)) + { + r = (float)(v*0.501); + } + var x1 = r; var z1 = lineCal.calZ(x1); - var x2 = -5; + var x2 = -r; var z2 = lineCal.calZ(x2); edgeLines.Add(new Tuple(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2))); lines.Add(DisplayLineModel3D(edgeLines, XlineColor)); @@ -1318,9 +1329,9 @@ public class ViewportHelperPro bindingMoveLine(lineE, lineF); Color4 YlineColor = new Color4(0F, 80f, 0f, 1f); - var x3 = 5; + var x3 = r; var z3 = lineCal.calZVertical(x3); - var x4 = -5; + var x4 = -r; var z4 = lineCal.calZVertical(x4); edgeLines = new List>(); @@ -1350,7 +1361,11 @@ public class ViewportHelperPro bindingMoveLine(lineG, lineH); return lines; } - + /// + /// 网状参考线 对向移动绑定 + /// + /// + /// private static void bindingMoveLine(LineGeometryModel3D lineA, LineGeometryModel3D lineB) { lineA.MouseDown3D += LineA_MouseDown3D; @@ -1386,7 +1401,7 @@ public class ViewportHelperPro var perpendicularDirection = Vector3D.CrossProduct(lineDirection.ToVector3D(), Vector3D.CrossProduct(moveDirection, lineDirection.ToVector3D())); perpendicularDirection.Normalize(); - double scaleFactor = 0.1; // 缩放因子 + double scaleFactor = 0.05; // 缩放因子 // 计算垂直距离 double perpendicularDistance = Vector3D.DotProduct(moveDirection, perpendicularDirection) * scaleFactor; System.Console.WriteLine("距离:"+ perpendicularDistance); @@ -1436,11 +1451,11 @@ public class ViewportHelperPro // 创建射线 var ray = new Ray3D( camera.Position, - new Vector3D(mousePosition.X - Viewport.ActualWidth / 2, -(mousePosition.Y - Viewport.ActualHeight / 2), -camera.Position.Z) + new Vector3D(mousePosition.X - Viewport.ActualWidth / 2, -camera.Position.Y, -(mousePosition.Y - Viewport.ActualHeight / 2) ) ); // 创建平面(假设平面为 Y=0) - var plane = new Plane3D(new Point3D(0, 0, 0), new Vector3D(0, 0, 1)); + var plane = new Plane3D(new Point3D(0, 0, 0), new Vector3D(0, 1, 0)); // 计算射线与平面的交点 var intersection = GetIntersection(ray, plane); @@ -1456,13 +1471,23 @@ public class ViewportHelperPro // 使用 Plane3D.LineIntersection 方法计算交点 return plane.LineIntersection(ray.Origin, rayEnd); } - + private static double initialRadius = 1.0; // 初始半径 + private static double endRadius = 1.0; // 拖拽后半径 + private static double initDistance = 1.0; // 初始与圆心之间距离 + private static double endDistance = 1.0; // 拖拽后与圆心之间距离 + private static Point dragStartPoint; + /// + /// 圆圈参考线 + /// + /// + /// + /// public static LineGeometryModel3D ShowCircleLine(double radius = 1.0, double thickness = 1.0) { var Y = -0.01F; var center = ViewportManager.CenterVector; center.Y = Y; - return UpdateCircleGeometry(center); + return UpdateCircleGeometry(center, initialRadius); } private static LineGeometryModel3D UpdateCircleGeometry(Vector3 center, double radius = 1.0) { @@ -1482,11 +1507,106 @@ public class ViewportHelperPro indices.Add(i); indices.Add((i + 1) % segments); } - + var Circle = DisplayLineModel3D(positions, Color4.Black); + Circle.MouseDown3D += Circle_MouseDown3D; + Circle.MouseUp3D += Circle_MouseUp3D; + Circle.MouseMove3D += Circle_MouseMove3D; // 更新圆形线的几何形状 - return DisplayLineModel3D(positions, Color4.Black); + return Circle; + } + + private static void Circle_MouseMove3D(object sender, RoutedEventArgs e) + { + if (isDrawing) + { + if (e is HelixToolkit.Wpf.SharpDX.MouseMove3DEventArgs ev) + { + var line = sender as LineGeometryModel3D; + + if (line==null) + { + return; + } + var MinRadius = 0.1; + var MaxRadius = (ViewportManager.ModelBounds.Maximum.X - ViewportManager.ModelBounds.Minimum.X) * 0.6; + // 现在鼠标对于3d模型的位置 + var mousePosition = ev.Position; + var Y = -0.01F; + var center = ViewportManager.CenterVector; + center.Y = Y; + + Point3D mouseWorldPosition = Get3DPointFromMouse(mousePosition); + + // 计算鼠标与圆心的距离 + double distance = CalculateDistance(mouseWorldPosition, center.ToPoint3D()); + + double scaleFactor = 0; + + if (distance < initDistance) + { + // 鼠标靠近圆心,缩小半径 + scaleFactor = -0.01; + } + else + { + // 鼠标远离圆心,扩大半径 + scaleFactor = +0.01; + } + + // 计算鼠标移动的距离(以屏幕坐标为单位) + double delta = (dragStartPoint - mousePosition).Length; + + // 计算新的半径 + double newRadius = initialRadius + delta * scaleFactor; // 缩放因子 + + // 限制半径范围 + newRadius = Math.Clamp(newRadius, MinRadius, MaxRadius); + + var scaleTransform = new ScaleTransform3D(newRadius, 1, newRadius); // 缩放变换 + line.Transform = scaleTransform; + endRadius = newRadius; + endDistance = distance; + } + } + } + // 计算两点之间的距离 + private static double CalculateDistance(Point3D p1, Point3D p2) + { + double dx = p2.X - p1.X; + double dy = p2.Y - p1.Y; + double dz = p2.Z - p1.Z; + + return Math.Sqrt(dx * dx + dy * dy + dz * dz); + } + private static void Circle_MouseUp3D(object sender, RoutedEventArgs e) + { + isDrawing = false; + var Viewport = ViewportManager.GetViewport3D(); + initialRadius = endRadius; + initDistance = endDistance; + // 释放鼠标捕获 + Viewport.ReleaseMouseCapture(); } + private static void Circle_MouseDown3D(object sender, RoutedEventArgs e) + { + isDrawing = true; + if (e is HelixToolkit.Wpf.SharpDX.MouseDown3DEventArgs ev) + { + var line = sender as LineGeometryModel3D; + + // 获取鼠标点击的位置 + dragStartPoint = ev.Position; + Point3D mouseWorldPosition = Get3DPointFromMouse(dragStartPoint); + var Y = -0.01F; + var center = ViewportManager.CenterVector; + center.Y = Y; + initDistance = CalculateDistance(mouseWorldPosition, center.ToPoint3D()); + var Viewport = ViewportManager.GetViewport3D(); + // 捕获鼠标 + Viewport.CaptureMouse(); + } + } #region 私有方法 /// diff --git a/Views/UserControl/ViewportData/Helper/ViewportManager.cs b/Views/UserControl/ViewportData/Helper/ViewportManager.cs index 399d6ec..94ef6db 100644 --- a/Views/UserControl/ViewportData/Helper/ViewportManager.cs +++ b/Views/UserControl/ViewportData/Helper/ViewportManager.cs @@ -278,6 +278,7 @@ public class ViewportManager _viewport.Camera.UpDirection = new Vector3D(0, -1, 0); _viewport.RenderHost.MSAA = MSAALevel.Maximum; // TODO: + MainModelMeshLines.Clear(); MainModelMeshLines.AddRange(ViewportHelperPro.ShowMeshLines(entities)); MainModelCircleLine = ViewportHelperPro.ShowCircleLine(); }