diff --git a/Views/UserControl/Viewport3D.xaml b/Views/UserControl/Viewport3D.xaml
index 138e33b..2c2ccfc 100644
--- a/Views/UserControl/Viewport3D.xaml
+++ b/Views/UserControl/Viewport3D.xaml
@@ -74,7 +74,6 @@
PreviewMouseRightButtonUp="UIElement_OnPreviewMouseRightButtonUp"
PreviewMouseRightButtonDown="UIElement_OnPreviewMouseRightButtonDown"
PreviewMouseMove="Viewport3Dx_OnPreviewMouseMove"
- MouseLeftButtonDown="Viewport3Dx_MouseLeftButtonDown"
MouseDoubleClick="Viewport3Dx_OnMouseLeftButtonDown">
diff --git a/Views/UserControl/Viewport3D.xaml.cs b/Views/UserControl/Viewport3D.xaml.cs
index 1dc994f..74a0429 100644
--- a/Views/UserControl/Viewport3D.xaml.cs
+++ b/Views/UserControl/Viewport3D.xaml.cs
@@ -596,28 +596,4 @@ public partial class Viewport3D
//Viewport3Dx.ShowTriangleCountInfo = !Viewport3Dx.ShowTriangleCountInfo;
}
- private void Viewport3Dx_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
- {
- var mousePosition = e.GetPosition(Viewport3Dx);
- var hits = Viewport3Dx.FindHits(mousePosition);
- // 如果没有命中任何 3D 对象
- //if (hits == null || hits.Count == 0)
- //{
- // ViewportManager.ClearDicModels();
- // return;
- //}
- //var hit = hits[0];
- //// 检查是否是 MeshGeometryModel3D
- //if (hit.ModelHit is LineGeometryModel3D modelHit)
- //{
- // // 获取几何信息
- // if (modelHit != null)
- // {
- // }
- //}
- //else
- //{
- // ViewportManager.ClearDicModels();
- //}
- }
}
\ No newline at end of file
diff --git a/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs b/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs
index d1397a3..e14f879 100644
--- a/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs
+++ b/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs
@@ -1,29 +1,23 @@
-using System.Collections.Frozen;
using System.Collections.ObjectModel;
-using System.Diagnostics;
-using System.Drawing.Text;
using System.IO;
-using System.Text.Json.Nodes;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
-using System.Windows.Threading;
-using HandyControl.Controls;
using HelixToolkit.Wpf.SharpDX;
using log4net;
-using NPOI.OpenXmlFormats.Vml.Office;
using SharpDX;
using SharpDX.Direct3D11;
-using SharpDX.DXGI;
using SparkClient.Views.UserControl.ViewportData.Enum;
using SparkClient.Views.UserControl.ViewportData.Entity;
using Color = SharpDX.Color;
using GeometryModel3D = HelixToolkit.Wpf.SharpDX.GeometryModel3D;
-using NPOI.SS.Formula.Functions;
using MeshGeometry3D = HelixToolkit.Wpf.SharpDX.MeshGeometry3D;
-using NPOI.SS.UserModel;
+using Point = System.Windows.Point;
+using PerspectiveCamera = HelixToolkit.Wpf.SharpDX.PerspectiveCamera;
+using System.Windows.Controls;
+
namespace SparkClient.Views.UserControl.ViewportData.Helper;
@@ -1331,7 +1325,8 @@ public class ViewportHelperPro
return lines;
}
private static bool isDrawing = false;
- private static Vector3 startpoint;
+ private static Point3D previousMousePosition;
+ private static Vector3D _totalTranslation = new Vector3D(0, 0, 0);
private static void LineA_MouseMove3D(object sender, RoutedEventArgs e)
{
if (isDrawing)
@@ -1339,15 +1334,40 @@ public class ViewportHelperPro
if (e is HelixToolkit.Wpf.SharpDX.MouseMove3DEventArgs ev)
{
var line = sender as LineGeometryModel3D;
- var newPoint = ev.HitTestResult.PointHit;
- var moveDirection = newPoint - startpoint;
+ 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();
- var perpendicularDirection = Vector3.Cross(lineDirection, Vector3.Cross(moveDirection, lineDirection));
+ Vector3D referenceVector = new Vector3D(0, 1, 0);
+ Vector3D perpendicularDirection = Vector3D.CrossProduct(lineDirection.ToVector3D(), referenceVector);
perpendicularDirection.Normalize();
- line.Geometry.Positions[0] += perpendicularDirection * Vector3.Dot(moveDirection, perpendicularDirection);
- line.Geometry.Positions[1] += perpendicularDirection * Vector3.Dot(moveDirection, perpendicularDirection);
+ 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;
+ 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;
}
}
}
@@ -1361,10 +1381,36 @@ public class ViewportHelperPro
{
isDrawing = true;
if(e is HelixToolkit.Wpf.SharpDX.MouseDown3DEventArgs ev){
- startpoint = ev.HitTestResult.PointHit;
+ // 获取鼠标点击的位置
+ 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;
+
}
}
+ private static Point3D Get3DPointFromMouse(Point mousePosition, Viewport3DX Viewport)
+ {
+ // 将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);
+
+ return intersection ?? new Point3D(0, 0, 0);
+ }
+
+ private static Ray3D GetRayFromMouse(Point mousePosition, Viewport3DX Viewport)
+ {
+ // 获取从相机发出的射线
+ 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();
+ return new Ray3D(camera.Position, rayDirection);
+ }
public static LineGeometryModel3D ShowCircleLine(double radius = 1.0, double thickness = 1.0)
{
@@ -1651,4 +1697,39 @@ public class ViewportHelperPro
#endregion
+}
+
+// 辅助类:表示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