From 818962f13cef854b01e3b0f6c1a0623d670f7bf7 Mon Sep 17 00:00:00 2001 From: sunhonglei Date: Fri, 17 Jan 2025 17:32:39 +0800 Subject: [PATCH 1/2] fix: --- Views/UserControl/Viewport3D.xaml.cs | 4 +- .../Helper/LineCalculationHelper.cs | 60 ++++++-- .../ViewportData/Helper/ViewportHelperPro.cs | 144 ++++++++++++++++-- .../ViewportData/Helper/ViewportManager.cs | 1 + 4 files changed, 181 insertions(+), 28 deletions(-) diff --git a/Views/UserControl/Viewport3D.xaml.cs b/Views/UserControl/Viewport3D.xaml.cs index 74a0429..3e6dc03 100644 --- a/Views/UserControl/Viewport3D.xaml.cs +++ b/Views/UserControl/Viewport3D.xaml.cs @@ -413,12 +413,14 @@ public partial class Viewport3D ViewportManager.ResetChooseAddModels(); break; case "ViewportRightMenuShowMeshLines": + var center = ViewportManager.ModelBounds.Center; var maxDimension = ViewportManager.ModelBounds.Size.Length(); var distance = maxDimension * 1.2; // 调整相机到模型的距离,保证视野范围内 - var center = ViewportManager.ModelBounds.Center; + // 获取当前相机 var camera = Viewport3Dx.Camera as HelixToolkit.Wpf.SharpDX.PerspectiveCamera; camera.Position = new Point3D(center.X, center.Y - distance, center.Z); // 从底部看,Y轴负方向 camera.UpDirection = new Vector3D(0, 0, -1); + camera.LookDirection = new Vector3D(center.X - camera.Position.X, center.Y - camera.Position.Y, center.Z - camera.Position.Z); ViewportManager.ShowMeshLines(checkResult); //camera.LookDirection = new Vector3D(center.X - camera.Position.X, center.Y - camera.Position.Y, center.Z - camera.Position.Z); diff --git a/Views/UserControl/ViewportData/Helper/LineCalculationHelper.cs b/Views/UserControl/ViewportData/Helper/LineCalculationHelper.cs index cdc7622..7789ba1 100644 --- a/Views/UserControl/ViewportData/Helper/LineCalculationHelper.cs +++ b/Views/UserControl/ViewportData/Helper/LineCalculationHelper.cs @@ -12,7 +12,7 @@ namespace SparkClient.Views.UserControl.ViewportData.Helper { private readonly float Y = -0.01F; private Vector3 point1; - private Vector3 point2; + private Vector3 center; /// /// 常数a(y=ax+b) /// @@ -21,21 +21,21 @@ namespace SparkClient.Views.UserControl.ViewportData.Helper /// 常数b(y=ax+b) /// private float b; - public LineCalculationHelper(Vector3 point1, Vector3 point2) { + public LineCalculationHelper(Vector3 point1, Vector3 center) { this.point1 = point1; - this.point2 = point2; - this.a = calA(point1, point2); + this.center = center; + this.a = calA(point1, center); this.b = calB(point1, a); } /// /// 常数a的计算 /// /// - /// + /// /// - private float calA(Vector3 point1, Vector3 point2) + private float calA(Vector3 point1, Vector3 center) { - return (point1.Z - point2.Z) / (point1.X - point2.X); + return (point1.Z - center.Z) / (point1.X - center.X); } /// /// 常数b的计算 @@ -50,18 +50,20 @@ namespace SparkClient.Views.UserControl.ViewportData.Helper public Tuple calXline(float length) { - var x1 = 5; - var z1 = calZ(x1); - var x2 = -5; - var z2 = calZ(x2); + var twoPoint = CalculatePointsOnLine(this.a,length); + var x1 = twoPoint.p1.X; + var z1 = twoPoint.p1.Y; + var x2 = twoPoint.p2.X; + var z2 = twoPoint.p2.X; return new Tuple(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)); } public Tuple calYline(float length) { - var x1 = 5; - var z1 = calZVertical(x1); - var x2 = -5; - var z2 = calZVertical(x2); + var twoPoint = CalculatePointsOnLine(-(1/a), length); + var x1 = twoPoint.p1.X; + var z1 = twoPoint.p1.Y; + var x2 = twoPoint.p2.X; + var z2 = twoPoint.p2.X; return new Tuple(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)); } @@ -95,5 +97,33 @@ namespace SparkClient.Views.UserControl.ViewportData.Helper { return (-x / a) + b + offset; } + + private ((float X, float Y) p1, (float X, float Y) p2) CalculatePointsOnLine(float k ,float L) + { + float x0 = center.X; + float y0 = center.Z; + // 将距离公式展开并整理为关于 t 的二次方程 + float A = 1 + k * k; + float B = -2 * x0 + 2 * k * (b - y0); + float C = x0 * x0 + (b - y0) * (b - y0) - L * L; + + // 计算判别式 + float discriminant = B * B - 4 * A * C; + + if (discriminant < 0) + { + throw new InvalidOperationException("无解:距离 L 太小,无法找到满足条件的点。"); + } + + // 计算 t 的两个解 + float t1 = (float)(-B + Math.Sqrt(discriminant)) / (2 * A); + float t2 = (float)(-B - Math.Sqrt(discriminant)) / (2 * A); + + // 计算两点坐标 + var p1 = (X: t1, Y: k * t1 + b); + var p2 = (X: t2, Y: k * t2 + b); + + return (p1, p2); + } } } diff --git a/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs b/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs index a7db89b..48d063d 100644 --- a/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs +++ b/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs @@ -1273,6 +1273,12 @@ 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(); @@ -1288,9 +1294,14 @@ public class ViewportHelperPro var edgeLines = new List>(); Color4 XlineColor =new Color4(80f, 0f, 0f, 1f); - var x1 = 5; + float r =5; + if(double.TryParse(ViewportManager.DiamondData["M2"].ToString(), out var v)) + { + r = (float)(v*0.501); + } + var x1 = r; var z1 = lineCal.calZ(x1); - var x2 = -5; + 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)); @@ -1318,9 +1329,9 @@ public class ViewportHelperPro bindingMoveLine(lineE, lineF); Color4 YlineColor = new Color4(0F, 80f, 0f, 1f); - var x3 = 5; + var x3 = r; var z3 = lineCal.calZVertical(x3); - var x4 = -5; + var x4 = -r; var z4 = lineCal.calZVertical(x4); edgeLines = new List>(); @@ -1350,7 +1361,11 @@ public class ViewportHelperPro bindingMoveLine(lineG, lineH); return lines; } - + /// + /// 网状参考线 对向移动绑定 + /// + /// + /// private static void bindingMoveLine(LineGeometryModel3D lineA, LineGeometryModel3D lineB) { lineA.MouseDown3D += LineA_MouseDown3D; @@ -1386,7 +1401,7 @@ public class ViewportHelperPro var perpendicularDirection = Vector3D.CrossProduct(lineDirection.ToVector3D(), Vector3D.CrossProduct(moveDirection, lineDirection.ToVector3D())); perpendicularDirection.Normalize(); - double scaleFactor = 0.1; // 缩放因子 + double scaleFactor = 0.05; // 缩放因子 // 计算垂直距离 double perpendicularDistance = Vector3D.DotProduct(moveDirection, perpendicularDirection) * scaleFactor; System.Console.WriteLine("距离:"+ perpendicularDistance); @@ -1436,11 +1451,11 @@ public class ViewportHelperPro // 创建射线 var ray = new Ray3D( camera.Position, - new Vector3D(mousePosition.X - Viewport.ActualWidth / 2, -(mousePosition.Y - Viewport.ActualHeight / 2), -camera.Position.Z) + new Vector3D(mousePosition.X - Viewport.ActualWidth / 2, -camera.Position.Y, -(mousePosition.Y - Viewport.ActualHeight / 2) ) ); // 创建平面(假设平面为 Y=0) - var plane = new Plane3D(new Point3D(0, 0, 0), new Vector3D(0, 0, 1)); + var plane = new Plane3D(new Point3D(0, 0, 0), new Vector3D(0, 1, 0)); // 计算射线与平面的交点 var intersection = GetIntersection(ray, plane); @@ -1456,13 +1471,23 @@ public class ViewportHelperPro // 使用 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; + /// + /// 圆圈参考线 + /// + /// + /// + /// public static LineGeometryModel3D ShowCircleLine(double radius = 1.0, double thickness = 1.0) { var Y = -0.01F; var center = ViewportManager.CenterVector; center.Y = Y; - return UpdateCircleGeometry(center); + return UpdateCircleGeometry(center, initialRadius); } private static LineGeometryModel3D UpdateCircleGeometry(Vector3 center, double radius = 1.0) { @@ -1482,11 +1507,106 @@ public class ViewportHelperPro indices.Add(i); indices.Add((i + 1) % segments); } - + var Circle = DisplayLineModel3D(positions, Color4.Black); + Circle.MouseDown3D += Circle_MouseDown3D; + Circle.MouseUp3D += Circle_MouseUp3D; + Circle.MouseMove3D += Circle_MouseMove3D; // 更新圆形线的几何形状 - return DisplayLineModel3D(positions, Color4.Black); + return Circle; + } + + private static void Circle_MouseMove3D(object sender, RoutedEventArgs e) + { + if (isDrawing) + { + if (e is HelixToolkit.Wpf.SharpDX.MouseMove3DEventArgs ev) + { + var line = sender as LineGeometryModel3D; + + if (line==null) + { + return; + } + var MinRadius = 0.1; + var MaxRadius = (ViewportManager.ModelBounds.Maximum.X - ViewportManager.ModelBounds.Minimum.X) * 0.6; + // 现在鼠标对于3d模型的位置 + var mousePosition = ev.Position; + var Y = -0.01F; + var center = ViewportManager.CenterVector; + center.Y = Y; + + Point3D mouseWorldPosition = Get3DPointFromMouse(mousePosition); + + // 计算鼠标与圆心的距离 + double distance = CalculateDistance(mouseWorldPosition, center.ToPoint3D()); + + double scaleFactor = 0; + + if (distance < initDistance) + { + // 鼠标靠近圆心,缩小半径 + scaleFactor = -0.01; + } + else + { + // 鼠标远离圆心,扩大半径 + scaleFactor = +0.01; + } + + // 计算鼠标移动的距离(以屏幕坐标为单位) + double delta = (dragStartPoint - mousePosition).Length; + + // 计算新的半径 + double newRadius = initialRadius + delta * scaleFactor; // 缩放因子 + + // 限制半径范围 + newRadius = Math.Clamp(newRadius, MinRadius, MaxRadius); + + var scaleTransform = new ScaleTransform3D(newRadius, 1, newRadius); // 缩放变换 + line.Transform = scaleTransform; + endRadius = newRadius; + endDistance = distance; + } + } + } + // 计算两点之间的距离 + private static double CalculateDistance(Point3D p1, Point3D p2) + { + double dx = p2.X - p1.X; + double dy = p2.Y - p1.Y; + double dz = p2.Z - p1.Z; + + return Math.Sqrt(dx * dx + dy * dy + dz * dz); + } + private static void Circle_MouseUp3D(object sender, RoutedEventArgs e) + { + isDrawing = false; + var Viewport = ViewportManager.GetViewport3D(); + initialRadius = endRadius; + initDistance = endDistance; + // 释放鼠标捕获 + Viewport.ReleaseMouseCapture(); } + private static void Circle_MouseDown3D(object sender, RoutedEventArgs e) + { + isDrawing = true; + if (e is HelixToolkit.Wpf.SharpDX.MouseDown3DEventArgs ev) + { + var line = sender as LineGeometryModel3D; + + // 获取鼠标点击的位置 + dragStartPoint = ev.Position; + Point3D mouseWorldPosition = Get3DPointFromMouse(dragStartPoint); + var Y = -0.01F; + var center = ViewportManager.CenterVector; + center.Y = Y; + initDistance = CalculateDistance(mouseWorldPosition, center.ToPoint3D()); + var Viewport = ViewportManager.GetViewport3D(); + // 捕获鼠标 + Viewport.CaptureMouse(); + } + } #region 私有方法 /// diff --git a/Views/UserControl/ViewportData/Helper/ViewportManager.cs b/Views/UserControl/ViewportData/Helper/ViewportManager.cs index 399d6ec..94ef6db 100644 --- a/Views/UserControl/ViewportData/Helper/ViewportManager.cs +++ b/Views/UserControl/ViewportData/Helper/ViewportManager.cs @@ -278,6 +278,7 @@ public class ViewportManager _viewport.Camera.UpDirection = new Vector3D(0, -1, 0); _viewport.RenderHost.MSAA = MSAALevel.Maximum; // TODO: + MainModelMeshLines.Clear(); MainModelMeshLines.AddRange(ViewportHelperPro.ShowMeshLines(entities)); MainModelCircleLine = ViewportHelperPro.ShowCircleLine(); } From b259b16696b305bbcce748d0ef4ec768ec7cbb93 Mon Sep 17 00:00:00 2001 From: sunhonglei Date: Sat, 18 Jan 2025 11:00:44 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=9B=BD=E9=99=85=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Language/en_US.xaml | 77 +++++++++++++++++++++++---------------------- Language/zh_CN.xaml | 11 +++---- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/Language/en_US.xaml b/Language/en_US.xaml index f04442b..4c3228b 100644 --- a/Language/en_US.xaml +++ b/Language/en_US.xaml @@ -2,13 +2,13 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=netstandard"> - Starshine + Spark - Start Detection + START MEASURE - Configuration + SYS SETTING - Help + HELP HELP NAME @@ -16,18 +16,18 @@ Detection Result Starting detection, please wait... - Import Template - Update and Save - Add Row + Import + Update + Add - Algorithm Configuration - Grading Configuration - Cutting Tool Configuration + Algorithm + Grading + Cut Machine Username or password incorrect, please try again - Delete Configuration - Import Configuration - Beautify Json - Compress Json + Delete + Import + Beautify + Compress Do you want to exit the program? @@ -35,19 +35,19 @@ Yes No Cancel - Confirm + OK Data saved successfully Data save failed No data imported - Parameters \\ Cutting Grade - GRADE_NAME - STANDARD_NAME - SHAPE_NAME - INSTITUTE_NAME - RULE_NAME + Parameters \ Cutting Grade + GRADE_EN_NAME + STANDARD_EN_NAME + SHAPE_EN_NAME + INSTITUTE_EN_NAME + RULE_EN_NAME - Please enter the diamond code to upload + Please enter the diamond code OK Skip No diamond code entered @@ -90,10 +90,10 @@ Save path does not exist - System Settings - General Settings - Model Settings - Save/Save + System + General + Model + Save Language Settings Upload Files TXT Files @@ -125,7 +125,7 @@ Lower Girdle Color Culet Color - Confirm + OK Cancel @@ -144,20 +144,21 @@ Show Similar Faces Show Defective Faces Show Positive Direction Mark + Show grid lines Save Successful Save Failed Select Path - Spark Diamond Detection System + SparkDetectionSystem Account Password Remember Password Login Exit System - If you forgot your password, please contact us + Forgot password, please contact the administrator - + Save Export DS @@ -168,16 +169,16 @@ Weight (ct) Cut Grade Symmetry Grade - Average - Deviation - Max Value - Min Value - Cut Level - SYM Level + Avg + Dev + Max + Min + Cut Grade + SYM Grade Facet 1 Are you sure you want to close the detection results screen? - + S001: Image capture in progress S002: Cache image cleared S003: Unable to send command to microcontroller @@ -197,5 +198,5 @@ CUDA not installed, program may encounter errors during execution MSVC Runtime not installed, program may encounter errors during execution File path does not exist - + The file format is incorrect diff --git a/Language/zh_CN.xaml b/Language/zh_CN.xaml index fd4985e..02263e1 100644 --- a/Language/zh_CN.xaml +++ b/Language/zh_CN.xaml @@ -24,7 +24,6 @@ 定级配置 切工仪配置 用户名或密码错误,请重试 - 删除配置 导入配置 美化Json @@ -41,14 +40,14 @@ 数据保存成功 数据保存失败 没有导入数据 - 参数 \\ 切工等级 + 参数 \ 切工等级 GRADE_NAME STANDARD_NAME SHAPE_NAME INSTITUTE_NAME RULE_NAME - 请输入上传钻石编码 + 请输入钻石编码 确定 跳过 没有输入钻石编码 @@ -179,7 +178,7 @@ 面1 是否关闭检测结果画面。 - + S001:采图正在进行中 S002:缓存图片被清理 S003:无法向单片机发送指令 @@ -194,10 +193,10 @@ P011:未检测到钻石 S007:请检查切工仪设备舱门是否关闭 - + 应用程序出现错误: CUDA未安装,程序执行中可能会出错 MSVC Runtime未安装,程序执行中可能会出错 文件路径不存在 - 定级配置文件格式不正 + 文件格式不正确 \ No newline at end of file