fix:线移动以及线绑定

master
sunhonglei 5 months ago
parent 12eadf0cd8
commit 2a9e87d613
  1. 1
      SparkClient.csproj
  2. 183
      Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs

@ -15,6 +15,7 @@
<PackageReference Include="HandyControl" Version="3.5.1" />
<PackageReference Include="HandyControl.Lang.en" Version="3.5.1" />
<PackageReference Include="HandyControls.Lang.zh-CN" Version="3.5.3" />
<PackageReference Include="HelixToolkit.Wpf" Version="2.25.0" />
<PackageReference Include="HelixToolkit.Wpf.SharpDX" Version="2.25.0" />
<PackageReference Include="log4net" Version="3.0.3" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.0" />

@ -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<Guid, Guid> moveLines = new Dictionary<Guid, Guid>();
public static List<LineGeometryModel3D> ShowMeshLines(List<Viewport3DTriangleEntity> entities, double thickness = 1.0)
{
moveLines = new();
List<LineGeometryModel3D> lines = new();
var Y = -0.01F;
var center = ViewportManager.CenterVector;
@ -1294,16 +1297,25 @@ public class ViewportHelperPro
edgeLines = new List<Tuple<Vector3, Vector3>>();
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(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<Tuple<Vector3, Vector3>>();
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(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<Tuple<Vector3, Vector3>>();
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)), 4));
var lineE = DisplayLineModel3D(edgeLines, XlineColor);
lines.Add(lineE);
edgeLines = new List<Tuple<Vector3, Vector3>>();
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(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<Tuple<Vector3, Vector3>>();
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(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<Tuple<Vector3, Vector3>>();
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(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<Tuple<Vector3, Vector3>>();
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x3, Y, z3), new Vector3(x4, Y, z4)), 4));
var lineG = DisplayLineModel3D(edgeLines, YlineColor);
lines.Add(lineG);
edgeLines = new List<Tuple<Vector3, Vector3>>();
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(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;
}
}
Loading…
Cancel
Save