From d2706d31c8238ee9e6430ab91ff9d2ddc887d509 Mon Sep 17 00:00:00 2001 From: sunhonglei Date: Thu, 23 Jan 2025 18:36:37 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E7=BD=91=E6=A0=BC=E7=BA=BF=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ViewModel/Grading/DiamondSelectVM.cs | 1 + .../ViewportData/Helper/ViewportHelperPro.cs | 258 +++++++----------- 2 files changed, 94 insertions(+), 165 deletions(-) diff --git a/ViewModel/Grading/DiamondSelectVM.cs b/ViewModel/Grading/DiamondSelectVM.cs index de2ab3f..b197fe9 100644 --- a/ViewModel/Grading/DiamondSelectVM.cs +++ b/ViewModel/Grading/DiamondSelectVM.cs @@ -319,6 +319,7 @@ public class DiamondSelectVM : BaseViewModel { AlgorithmResultEntity parameter = new AlgorithmResultEntity(); JsonImport jsonImport = new JsonImport(); + jsonImport.FilePath.Text = "D:\\项目\\TEST240.json"; bool? a = jsonImport.ShowDialog(); if (a ?? false) { diff --git a/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs b/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs index c6466b8..40ff913 100644 --- a/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs +++ b/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs @@ -1302,8 +1302,7 @@ public class ViewportHelperPro center.Y = Y; Viewport3DTriangleEntity firstPoint = ViewportManager.ViewportTriangle.Where(x => x.PlaneType == PlaneType.TableFacet).FirstOrDefault(); - //var b = ((center.Z * firstPoint.Point1.X) - (firstPoint.Point1.Z * center.X)) / (firstPoint.Point1.X - center.X); - //var a = (firstPoint.Point1.Z - b) / firstPoint.Point1.X; + var lineCal = new LineCalculationHelper(firstPoint.Point1, center); var edgeLines = new List>(); @@ -1313,13 +1312,7 @@ public class ViewportHelperPro { r = (float)(v*0.51); } - //var x1 = r; - //var z1 = lineCal.calZ(x1); - //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)); - + edgeLines = new List>(); var XLine = lineCal.calXline(r); edgeLines.Add(XLine); @@ -1348,15 +1341,6 @@ public class ViewportHelperPro bindingMoveLine(lineE, lineF); Color4 YlineColor = new Color4(0F, 80f, 0f, 1f); - //var x3 = r; - //var z3 = lineCal.calZVertical(x3); - //var x4 = -r; - //var z4 = lineCal.calZVertical(x4); - - //edgeLines = new List>(); - //edgeLines.Add(new Tuple(new Vector3(x3, Y, z3), new Vector3(x4, Y, z4))); - //lines.Add(DisplayLineModel3D(edgeLines, YlineColor)); - edgeLines = new List>(); var YLine = lineCal.calYline(r); edgeLines.Add(YLine); @@ -1405,21 +1389,18 @@ public class ViewportHelperPro moveLines.Add(lineB.GUID, lineA.GUID); } private static bool isDrawing = false; - private static Point3D previousMousePosition; - private static bool isOutOfRange = false; - + private static Point startDragPoint = new Point(); + private static Transform3D initialTransform; + private static Transform3D initialOtherTransform; private static void LineA_MouseMove3D(object sender, RoutedEventArgs e) { if (isDrawing) { if (e is HelixToolkit.Wpf.SharpDX.MouseMove3DEventArgs ev) { + var line = sender as LineGeometryModel3D; + var Y = line.Geometry.Positions[0].Y; // 定义中心点和半径 - var Y = -0.01F; - if (!IsCrown()) - { - Y = ViewportManager.ModelBounds.Maximum.Y + 0.01f; - } var center = ViewportManager.CenterVector; center.Y = Y; double radius = 5; @@ -1427,34 +1408,41 @@ public class ViewportHelperPro { radius = (v * 0.5); } - double minDistance = 0.01; // 最小距离 - var line = sender as LineGeometryModel3D; + + var minDistance = 0.01; // 直线方向分量 var lineDirection = line.Geometry.Positions[1] - line.Geometry.Positions[0]; lineDirection.Normalize(); // 现在鼠标对于3d模型的位置 var mousePosition = ev.Position; var currentMousePosition = Get3DPointFromMouse(mousePosition); - + currentMousePosition.Y = Y; + var hitPoint = Get3DPointFromMouse(startDragPoint); + hitPoint.Y = Y; // 计算鼠标移动的方向 - var moveDirection = previousMousePosition - currentMousePosition; - + var moveDirection = currentMousePosition - hitPoint; // 计算垂直于线的移动分量 var perpendicularDirection = Vector3D.CrossProduct(lineDirection.ToVector3D(), Vector3D.CrossProduct(moveDirection, lineDirection.ToVector3D())); perpendicularDirection.Normalize(); - double scaleFactor = 13000; // 缩放因子 + double scaleFactor = 0.7; // 缩放因子 // 计算垂直距离 - double perpendicularDistance = Vector3D.DotProduct(moveDirection, perpendicularDirection) * scaleFactor; + double perpendicularDistance = Vector3D.DotProduct(moveDirection, perpendicularDirection); + // 垂直方向偏移量 - Vector3D projectedVector = perpendicularDistance * perpendicularDirection; + Vector3D projectedVector = perpendicularDistance * perpendicularDirection * scaleFactor; projectedVector.Y = 0; - + Console.WriteLine($"距离:{perpendicularDistance}\t 移动分量:{perpendicularDirection.X},{perpendicularDirection.Y},{perpendicularDirection.Z}\t偏移量:{projectedVector.X},\t{projectedVector.Z}"); // 计算直线的新位置 var transform = new TranslateTransform3D(projectedVector); - var newPosition1 = line.Geometry.Positions[0].ToVector3D() + projectedVector; - var newPosition2 = line.Geometry.Positions[1].ToVector3D() + projectedVector; - + var newTransform = new MatrixTransform3D(transform.Value * initialTransform.Value); + var newProjectedVector = new Vector3D(newTransform.Matrix.OffsetX ,Y, newTransform.Matrix.OffsetZ); + var newPosition1 = line.Geometry.Positions[0].ToVector3D(); + newPosition1.X += newTransform.Matrix.OffsetX; + newPosition1.Z += newTransform.Matrix.OffsetZ; + var newPosition2 = line.Geometry.Positions[1].ToVector3D(); + newPosition2.X += newTransform.Matrix.OffsetX; + newPosition2.Z += newTransform.Matrix.OffsetZ; // 计算直线的新中心点 Point3D newCenter = new Point3D( (newPosition1.X + newPosition2.X) / 2, @@ -1462,58 +1450,45 @@ public class ViewportHelperPro (newPosition1.Z + newPosition2.Z) / 2 ); - // 计算当前中心点与中心点的距离 - double currentDistance = (newCenter - center.ToPoint3D()).Length; - // 计算上一帧中心点与中心点的距离 Point3D previousCenter = new Point3D( (line.Geometry.Positions[0].X + line.Geometry.Positions[1].X) / 2, (line.Geometry.Positions[0].Y + line.Geometry.Positions[1].Y) / 2, (line.Geometry.Positions[0].Z + line.Geometry.Positions[1].Z) / 2 ); - - double previousDistance = (previousCenter - center.ToPoint3D()).Length; - // 检查移动方向 - bool isMovingAway = currentDistance > previousDistance; // 是否远离中心点 - if (isMovingAway) - { - isOutOfRange = false; - }else if (isOutOfRange) - { - Logger.Info("超出范围,停止移动"); - } + // 检查新中心点是否满足距离条件 if (IsPointInRange(newCenter, center.ToPoint3D(), radius, minDistance)) { } - else if(isMovingAway) + else { //// 如果新中心点不满足条件,将位置限制在范围内 //projectedVector = LimitToRange(newCenter, center.ToPoint3D(), radius, minDistance) - newCenter; // 如果新中心点超出范围,将直线位置固定到最大允许位置 Point3D maxCenter = LimitToMaxPosition(center.ToPoint3D(), radius, newCenter); // 计算直线的起点和终点在最大允许位置 - projectedVector = maxCenter - previousCenter; + newProjectedVector = maxCenter - previousCenter; projectedVector.Y = 0; - transform = new TranslateTransform3D(projectedVector); + + transform = new TranslateTransform3D(newProjectedVector); + newTransform = new MatrixTransform3D(transform.Value); //Logger.Info($"X:{projectedVector.X},Z:{projectedVector.Z}"); Logger.Info("超出范围,停止移动"); - }else if(!isMovingAway) - { - isOutOfRange = true; - Logger.Info("isOutOfRange = true;"); } - line.Transform = transform; + + line.Transform = newTransform; + // 更新上一帧的鼠标位置 - //previousMousePosition = currentMousePosition; + // previousMousePosition = currentMousePosition; var otherLineGuid = moveLines[line.GUID]; var Viewport = ViewportManager.GetViewport3D(); var otherLine = Viewport.Items.Where(x => x.GUID == otherLineGuid).FirstOrDefault(); if (otherLine != null) { - var transform_other = new TranslateTransform3D(-projectedVector); - otherLine.Transform = transform_other; + var otherTranslateTransform = new TranslateTransform3D(-newProjectedVector); + otherLine.Transform = otherTranslateTransform; } } } @@ -1536,34 +1511,12 @@ public class ViewportHelperPro return center + direction * radius; } - // 将点限制在范围内(距离大于 minDistance 且小于等于 radius) - private static Point3D LimitToRange(Point3D point, Point3D center, double radius, double minDistance) - { - Vector3D direction = point - center; - double distance = direction.Length; - - if (distance <= minDistance) - { - // 如果距离小于等于最小距离,将点偏移到最小距离处 - direction.Normalize(); - return center + direction * minDistance; - } - else if (distance > radius) - { - // 如果距离大于半径,将点限制在半径范围内 - direction.Normalize(); - return center + direction * radius; - } - - // 如果距离在范围内,直接返回点 - return point; - } - private static void LineA_MouseUp3D(object sender, RoutedEventArgs e) { isDrawing = false; var Viewport = ViewportManager.GetViewport3D(); Viewport.Cursor = Cursors.Arrow; + startDragPoint = new Point(); } private static void LineA_MouseDown3D(object sender, RoutedEventArgs e) @@ -1572,9 +1525,16 @@ public class ViewportHelperPro if(e is HelixToolkit.Wpf.SharpDX.MouseDown3DEventArgs ev){ var Viewport = ViewportManager.GetViewport3D(); Viewport.Cursor = Cursors.SizeAll; - // 获取鼠标点击的位置 - var mousePosition = ev.Position; - previousMousePosition = Get3DPointFromMouse(mousePosition); + startDragPoint = ev.Position; + var line = sender as LineGeometryModel3D; + initialTransform = line.Transform ?? Transform3D.Identity; + // var line = sender as LineGeometryModel3D; + var otherLineGuid = moveLines[line.GUID]; + var otherLine = Viewport.Items.Where(x => x.GUID == otherLineGuid).FirstOrDefault(); + if (otherLine!= null) + { + initialOtherTransform = otherLine.Transform ?? Transform3D.Identity; + } } } private static Point3D Get3DPointFromMouse(Point mousePosition) @@ -1584,9 +1544,8 @@ public class ViewportHelperPro // 获取射线 var ray = GetRayFromMouse(mousePosition, Viewport); - // 创建平面(假设平面为 Y=0) - var plane = new Plane3D(new Point3D(0, 0, 0), new Vector3D(0, 1, 0)); + var plane = new Plane3D(new Point3D(0,0,0), new Vector3D(0, 1, 0)); // 计算射线与平面的交点 var intersection = GetIntersection(ray, plane); @@ -1606,47 +1565,47 @@ public class ViewportHelperPro (float)(2.0 * mousePosition.X / viewport.ActualWidth - 1.0), (float)(1.0 - 2.0 * mousePosition.Y / viewport.ActualHeight) ); - // 使用 UnProject 方法获取射线 - var ray = viewport.UnProject(ndc); - + // var ray = viewport.UnProject(ndc); + var cameraPosition = viewport.Camera.Position; + var cameraLookDirection = viewport.Camera.LookDirection; + var cameraUpDirection = viewport.Camera.UpDirection; + var cameraRightDirection = Vector3D.CrossProduct(cameraLookDirection, cameraUpDirection); + var ray = (cameraLookDirection + ndc.X * cameraRightDirection + ndc.Y * cameraUpDirection); + ray.Normalize(); // 返回射线 - return new Ray3D(ray.Position.ToPoint3D(), ray.Direction.ToPoint3D()); + return new Ray3D(cameraPosition, ray); } - //private static Point3D? GetIntersection(Ray3D ray, Plane3D plane) - //{ - // // 计算射线方向与平面法向量的点积 - // double denominator = Vector3D.DotProduct(ray.Direction, plane.Normal); + private static Point3D? GetIntersection(Ray3D ray, Plane3D plane) + { + // 计算射线方向与平面法向量的点积 + double denominator = Vector3D.DotProduct(ray.Direction, plane.Normal); - // // 如果点积为 0,说明射线与平面平行,没有交点 - // if (Math.Abs(denominator) < 1e-6) - // return null; + // 如果点积为 0,说明射线与平面平行,没有交点 + if (Math.Abs(denominator) < 1e-6) + return null; - // // 计算射线起点到平面的距离 - // double t = Vector3D.DotProduct(plane.Position - ray.Origin, plane.Normal) / denominator; + // 计算射线起点到平面的距离 + double t = Vector3D.DotProduct(plane.Position - ray.Origin, plane.Normal) / denominator; - // // 如果 t 为负数,说明交点在射线起点后方 - // if (t < 0) - // return null; + // 如果 t 为负数,说明交点在射线起点后方 + if (t < 0) + return null; - // // 返回交点 - // return ray.Origin + ray.Direction * t; - //} + // 返回交点 + return ray.Origin + ray.Direction * t; + } - private static Point3D? GetIntersection(Ray3D ray, Plane3D plane) - { - // 将射线转换为直线(起点和终点) - Point3D rayEnd = ray.Origin + ray.Direction * 1000; // 延长射线 + //private static Point3D? GetIntersection(Ray3D ray, Plane3D plane) + //{ + // // 将射线转换为直线(起点和终点) + // Point3D rayEnd = ray.Origin + ray.Direction * 1000; // 延长射线 - // 使用 Plane3D.LineIntersection 方法计算交点 - return plane.LineIntersection(ray.Origin, rayEnd); - } + // // 使用 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; /// /// 圆圈参考线 /// @@ -1662,7 +1621,12 @@ public class ViewportHelperPro } var center = ViewportManager.CenterVector; center.Y = Y; - return UpdateCircleGeometry(center, initialRadius, thickness); + var Circle = UpdateCircleGeometry(center, initialRadius, thickness); + Circle.HitTestThickness = HitTestThickness; + Circle.MouseDown3D += Circle_MouseDown3D; + Circle.MouseUp3D += Circle_MouseUp3D; + Circle.MouseMove3D += Circle_MouseMove3D; + return Circle; } private static LineGeometryModel3D UpdateCircleGeometry(Vector3 center, double radius = 1.0, double thickness = 1.0) { @@ -1683,10 +1647,7 @@ public class ViewportHelperPro indices.Add((i + 1) % segments); } var Circle = DisplayLineModel3D(positions, Colors.Orange.ToColor4(),thickness); - Circle.HitTestThickness = HitTestThickness; - Circle.MouseDown3D += Circle_MouseDown3D; - Circle.MouseUp3D += Circle_MouseUp3D; - Circle.MouseMove3D += Circle_MouseMove3D; + // 更新圆形线的几何形状 return Circle; } @@ -1707,45 +1668,26 @@ public class ViewportHelperPro var MaxRadius = (ViewportManager.ModelBounds.Maximum.X - ViewportManager.ModelBounds.Minimum.X) * 0.6; // 现在鼠标对于3d模型的位置 var mousePosition = ev.Position; - var Y = -0.01F; - if (!IsCrown()) - { - Y = ViewportManager.ModelBounds.Maximum.Y + 0.01F; - } + var Y = line.Geometry.Positions[0].Y; var center = ViewportManager.CenterVector; center.Y = Y; Point3D mouseWorldPosition = Get3DPointFromMouse(mousePosition); - + mouseWorldPosition.Y = Y; + // Console.WriteLine($"鼠标在3D模型中的位置:{mouseWorldPosition.X},{mouseWorldPosition.Y},{mouseWorldPosition.Z}"); // 计算鼠标与圆心的距离 double distance = CalculateDistance(mouseWorldPosition, center.ToPoint3D()); - Console.WriteLine($"与圆心之间距离{distance}"); - double scaleFactor = 0; - - if (distance < initDistance) - { - // 鼠标靠近圆心,缩小半径 - scaleFactor = -1; - } - else - { - // 鼠标远离圆心,扩大半径 - scaleFactor = +1; - } - - // 计算鼠标移动的距离(以屏幕坐标为单位) - double delta = (dragStartPoint - mousePosition).Length; + // Console.WriteLine($"与圆心之间距离{distance}"); + double scaleFactor = 0.7; // 计算新的半径 - double newRadius = initialRadius + (distance - initDistance)*11000; // 缩放因子 + double newRadius = distance * scaleFactor; // 缩放因子 // 限制半径范围 newRadius = Math.Clamp(newRadius, MinRadius, MaxRadius); var scaleTransform = new ScaleTransform3D(newRadius, 1, newRadius); // 缩放变换 line.Transform = scaleTransform; - endRadius = newRadius; - endDistance = distance; } } } @@ -1763,8 +1705,6 @@ public class ViewportHelperPro isDrawing = false; var Viewport = ViewportManager.GetViewport3D(); Viewport.Cursor = Cursors.Arrow; - initialRadius = endRadius; - initDistance = endDistance; // 释放鼠标捕获 Viewport.ReleaseMouseCapture(); } @@ -1775,18 +1715,6 @@ public class ViewportHelperPro if (e is HelixToolkit.Wpf.SharpDX.MouseDown3DEventArgs ev) { var line = sender as LineGeometryModel3D; - - // 获取鼠标点击的位置 - dragStartPoint = ev.Position; - Point3D mouseWorldPosition = Get3DPointFromMouse(dragStartPoint); - var Y = -0.01F; - if(!IsCrown()) - { - Y = ViewportManager.ModelBounds.Maximum.Y + 0.01F; - } - var center = ViewportManager.CenterVector; - center.Y = Y; - initDistance = CalculateDistance(mouseWorldPosition, center.ToPoint3D()); var Viewport = ViewportManager.GetViewport3D(); Viewport.Cursor = Cursors.SizeAll; // 捕获鼠标