diff --git a/SparkClient.csproj b/SparkClient.csproj index 999d941..62c3379 100644 --- a/SparkClient.csproj +++ b/SparkClient.csproj @@ -15,6 +15,7 @@ + diff --git a/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs b/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs index e14f879..a7db89b 100644 --- a/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs +++ b/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs @@ -17,6 +17,8 @@ using MeshGeometry3D = HelixToolkit.Wpf.SharpDX.MeshGeometry3D; using Point = System.Windows.Point; using PerspectiveCamera = HelixToolkit.Wpf.SharpDX.PerspectiveCamera; using System.Windows.Controls; +using HelixToolkit.Wpf; +using MeshBuilder = HelixToolkit.Wpf.SharpDX.MeshBuilder; namespace SparkClient.Views.UserControl.ViewportData.Helper; @@ -1270,9 +1272,10 @@ 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(); List lines = new(); var Y = -0.01F; var center = ViewportManager.CenterVector; @@ -1294,16 +1297,25 @@ public class ViewportHelperPro edgeLines = new List>(); edgeLines.Add(lineCal.calLineOfOffset(new Tuple(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)),2)); - var lineA = DisplayLineModel3D(edgeLines, Color4.Black); + var lineA = DisplayLineModel3D(edgeLines, XlineColor); lines.Add(lineA); - + edgeLines = new List>(); edgeLines.Add(lineCal.calLineOfOffset(new Tuple(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)), -2)); var lineB = DisplayLineModel3D(edgeLines, XlineColor); lines.Add(lineB); - lineA.MouseDown3D += LineA_MouseDown3D; - lineA.MouseUp3D += LineA_MouseUp3D; - lineA.MouseMove3D += LineA_MouseMove3D; + bindingMoveLine(lineA, lineB); + + edgeLines = new List>(); + edgeLines.Add(lineCal.calLineOfOffset(new Tuple(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)), 4)); + var lineE = DisplayLineModel3D(edgeLines, XlineColor); + lines.Add(lineE); + + edgeLines = new List>(); + edgeLines.Add(lineCal.calLineOfOffset(new Tuple(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)), -4)); + var lineF = DisplayLineModel3D(edgeLines, XlineColor); + lines.Add(lineF); + bindingMoveLine(lineE, lineF); Color4 YlineColor = new Color4(0F, 80f, 0f, 1f); var x3 = 5; @@ -1317,16 +1329,42 @@ public class ViewportHelperPro edgeLines = new List>(); edgeLines.Add(lineCal.calLineOfOffset(new Tuple(new Vector3(x3, Y, z3), new Vector3(x4, Y, z4)), 2)); - lines.Add(DisplayLineModel3D(edgeLines, YlineColor)); + var lineC = DisplayLineModel3D(edgeLines, YlineColor); + lines.Add(lineC); edgeLines = new List>(); edgeLines.Add(lineCal.calLineOfOffset(new Tuple(new Vector3(x3, Y, z3), new Vector3(x4, Y, z4)), -2)); - lines.Add(DisplayLineModel3D(edgeLines, YlineColor)); + var lineD = DisplayLineModel3D(edgeLines, YlineColor); + lines.Add(lineD); + bindingMoveLine(lineC, lineD); + + edgeLines = new List>(); + edgeLines.Add(lineCal.calLineOfOffset(new Tuple(new Vector3(x3, Y, z3), new Vector3(x4, Y, z4)), 4)); + var lineG = DisplayLineModel3D(edgeLines, YlineColor); + lines.Add(lineG); + + edgeLines = new List>(); + edgeLines.Add(lineCal.calLineOfOffset(new Tuple(new Vector3(x3, Y, z3), new Vector3(x4, Y, z4)), -4)); + var lineH = DisplayLineModel3D(edgeLines, YlineColor); + lines.Add(lineH); + bindingMoveLine(lineG, lineH); return lines; } + + private static void bindingMoveLine(LineGeometryModel3D lineA, LineGeometryModel3D lineB) + { + lineA.MouseDown3D += LineA_MouseDown3D; + lineA.MouseUp3D += LineA_MouseUp3D; + lineA.MouseMove3D += LineA_MouseMove3D; + moveLines.Add(lineA.GUID, lineB.GUID); + lineB.MouseDown3D += LineA_MouseDown3D; + lineB.MouseUp3D += LineA_MouseUp3D; + lineB.MouseMove3D += LineA_MouseMove3D; + moveLines.Add(lineB.GUID, lineA.GUID); + } private static bool isDrawing = false; private static Point3D previousMousePosition; - private static Vector3D _totalTranslation = new Vector3D(0, 0, 0); + private static void LineA_MouseMove3D(object sender, RoutedEventArgs e) { if (isDrawing) @@ -1334,40 +1372,43 @@ public class ViewportHelperPro if (e is HelixToolkit.Wpf.SharpDX.MouseMove3DEventArgs ev) { var line = sender as LineGeometryModel3D; - var mousePosition = ev.Position; - var hitResult = ev.Viewport.FindNearestPoint(mousePosition); - if (hitResult == null) - { - return; - } + // 直线方向分量 var lineDirection = line.Geometry.Positions[1] - line.Geometry.Positions[0]; lineDirection.Normalize(); + // 现在鼠标对于3d模型的位置 + var mousePosition = ev.Position; + var currentMousePosition = Get3DPointFromMouse(mousePosition); - Vector3D referenceVector = new Vector3D(0, 1, 0); - Vector3D perpendicularDirection = Vector3D.CrossProduct(lineDirection.ToVector3D(), referenceVector); + // 计算鼠标移动的方向 + var moveDirection = previousMousePosition - currentMousePosition; + + // 计算垂直于线的移动分量 + var perpendicularDirection = Vector3D.CrossProduct(lineDirection.ToVector3D(), Vector3D.CrossProduct(moveDirection, lineDirection.ToVector3D())); perpendicularDirection.Normalize(); - var currentMousePosition = Get3DPointFromMouse(mousePosition, ev.Viewport); - //// 计算垂直于线的移动分量 - //var perpendicularDirection = Vector3.Cross(lineDirection, Vector3.Cross(moveDirection,lineDirection)); - //perpendicularDirection.Normalize(); - - var point = hitResult.Value; - - var dragVector = point - ev.HitTestResult.PointHit.ToPoint3D(); - double dotProduct = Vector3D.DotProduct(dragVector, perpendicularDirection); - Vector3D projectedVector = dotProduct * perpendicularDirection; + double scaleFactor = 0.1; // 缩放因子 + // 计算垂直距离 + double perpendicularDistance = Vector3D.DotProduct(moveDirection, perpendicularDirection) * scaleFactor; + System.Console.WriteLine("距离:"+ perpendicularDistance); + // 垂直方向偏移量 + Vector3D projectedVector = perpendicularDistance * perpendicularDirection; projectedVector.Y = 0; - //// 计算垂直距离 - //float perpendicularDistance = Vector3.Dot(moveDirection, perpendicularDirection); - //line.Geometry.Positions[0] += perpendicularDirection * perpendicularDistance; - - //line.Geometry.Positions[1] += perpendicularDirection * perpendicularDistance; - - _totalTranslation += projectedVector; var transform = new TranslateTransform3D(projectedVector); line.Transform = transform; + // 更新上一帧的鼠标位置 + //previousMousePosition = currentMousePosition; + var otherLineGuid = moveLines[line.GUID]; + var Viewport = ViewportManager.GetViewport3D(); + var otherLine = Viewport.Items.Where(x=>x.GUID == otherLineGuid).FirstOrDefault(); + if (otherLine!= null ) + { + Vector3D projectedVector_other = -perpendicularDistance * perpendicularDirection; + projectedVector_other.Y = 0; + var transform_other = new TranslateTransform3D(projectedVector_other); + otherLine.Transform = transform_other; + } + } } } @@ -1383,33 +1424,37 @@ public class ViewportHelperPro if(e is HelixToolkit.Wpf.SharpDX.MouseDown3DEventArgs ev){ // 获取鼠标点击的位置 var mousePosition = ev.Position; - var a = ev.Viewport; - previousMousePosition = Get3DPointFromMouse(mousePosition, a); - - var line = sender as LineGeometryModel3D; - //var transform = new TranslateTransform3D(10, 0, 10); - //line.Transform = transform; - + previousMousePosition = Get3DPointFromMouse(mousePosition); } } - private static Point3D Get3DPointFromMouse(Point mousePosition, Viewport3DX Viewport) + private static Point3D Get3DPointFromMouse(Point mousePosition) { - // 将2D屏幕坐标转换为3D世界坐标 - var ray = GetRayFromMouse(mousePosition, Viewport); - var plane = new Plane3D(new Point3D(0, 0, 0), new Vector3D(0, 0, 1)); // 假设平面为Z=0 - var intersection = plane.IntersectWith(ray); + // 使用 HelixToolkit 的 Ray3D 和 Plane3D + var Viewport = ViewportManager.GetViewport3D(); + var camera = Viewport.Camera as PerspectiveCamera; + + // 创建射线 + var ray = new Ray3D( + camera.Position, + new Vector3D(mousePosition.X - Viewport.ActualWidth / 2, -(mousePosition.Y - Viewport.ActualHeight / 2), -camera.Position.Z) + ); + + // 创建平面(假设平面为 Y=0) + var plane = new Plane3D(new Point3D(0, 0, 0), new Vector3D(0, 0, 1)); + + // 计算射线与平面的交点 + var intersection = GetIntersection(ray, plane); return intersection ?? new Point3D(0, 0, 0); } - private static Ray3D GetRayFromMouse(Point mousePosition, Viewport3DX Viewport) + private static Point3D? GetIntersection(Ray3D ray, Plane3D plane) { - // 获取从相机发出的射线 - var camera = Viewport.Camera as PerspectiveCamera; - var rayDirection = new Vector3D(mousePosition.X - Viewport.ActualWidth / 2, -(mousePosition.Y - Viewport.ActualHeight / 2), -camera.Position.Z); - rayDirection.Normalize(); + // 将射线转换为直线(起点和终点) + Point3D rayEnd = ray.Origin + ray.Direction * 1000; // 延长射线 - return new Ray3D(camera.Position, rayDirection); + // 使用 Plane3D.LineIntersection 方法计算交点 + return plane.LineIntersection(ray.Origin, rayEnd); } public static LineGeometryModel3D ShowCircleLine(double radius = 1.0, double thickness = 1.0) @@ -1699,37 +1744,3 @@ public class ViewportHelperPro } -// 辅助类:表示3D射线 -public class Ray3D -{ - public Point3D Origin { get; } - public Vector3D Direction { get; } - - public Ray3D(Point3D origin, Vector3D direction) - { - Origin = origin; - Direction = direction; - } -} - -// 辅助类:表示3D平面 -public class Plane3D -{ - public Point3D Point { get; } - public Vector3D Normal { get; } - - public Plane3D(Point3D point, Vector3D normal) - { - Point = point; - Normal = normal; - } - - public Point3D? IntersectWith(Ray3D ray) - { - var denominator = Vector3D.DotProduct(ray.Direction, Normal); - if (Math.Abs(denominator) < 1e-6) return null; // 平行,无交点 - - var t = Vector3D.DotProduct(Point - ray.Origin, Normal) / denominator; - return ray.Origin + t * ray.Direction; - } -} \ No newline at end of file