fix:网格线优化

master
sunhonglei 5 months ago
parent a0a5a249d4
commit d2706d31c8
  1. 1
      ViewModel/Grading/DiamondSelectVM.cs
  2. 250
      Views/UserControl/ViewportData/Helper/ViewportHelperPro.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)
{

@ -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<Tuple<Vector3, Vector3>>();
@ -1313,12 +1312,6 @@ 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<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)));
//lines.Add(DisplayLineModel3D(edgeLines, XlineColor));
edgeLines = new List<Tuple<Vector3, Vector3>>();
var XLine = lineCal.calXline(r);
@ -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<Tuple<Vector3, Vector3>>();
//edgeLines.Add(new Tuple<Vector3, Vector3>(new Vector3(x3, Y, z3), new Vector3(x4, Y, z4)));
//lines.Add(DisplayLineModel3D(edgeLines, YlineColor));
edgeLines = new List<Tuple<Vector3, Vector3>>();
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,9 +1450,6 @@ 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,
@ -1472,39 +1457,29 @@ public class ViewportHelperPro
(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;
var otherLineGuid = moveLines[line.GUID];
@ -1512,8 +1487,8 @@ public class ViewportHelperPro
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,7 +1544,6 @@ public class ViewportHelperPro
// 获取射线
var ray = GetRayFromMouse(mousePosition, Viewport);
// 创建平面(假设平面为 Y=0)
var plane = new Plane3D(new Point3D(0,0,0), new Vector3D(0, 1, 0));
@ -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;
/// <summary>
/// 圆圈参考线
/// </summary>
@ -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;
// 捕获鼠标

Loading…
Cancel
Save