Merge remote-tracking branch 'origin/master'

master
handefeng 5 months ago
commit 7f7e5425cc
  1. 77
      Language/en_US.xaml
  2. 11
      Language/zh_CN.xaml
  3. 4
      Views/UserControl/Viewport3D.xaml.cs
  4. 60
      Views/UserControl/ViewportData/Helper/LineCalculationHelper.cs
  5. 144
      Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs
  6. 1
      Views/UserControl/ViewportData/Helper/ViewportManager.cs

@ -2,13 +2,13 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=netstandard"> xmlns:sys="clr-namespace:System;assembly=netstandard">
<!--Text--> <!--Text-->
<sys:String x:Key="ProcName">Starshine</sys:String> <sys:String x:Key="ProcName">Spark</sys:String>
<sys:String x:Key="StartTest">Start Detection</sys:String> <sys:String x:Key="StartTest">START</sys:String>
<sys:String x:Key="StartTestFan">MEASURE</sys:String> <sys:String x:Key="StartTestFan">MEASURE</sys:String>
<sys:String x:Key="Config">Configuration</sys:String> <sys:String x:Key="Config">SYS</sys:String>
<sys:String x:Key="ConfigFan">SETTING</sys:String> <sys:String x:Key="ConfigFan">SETTING</sys:String>
<sys:String x:Key="Help">Help</sys:String> <sys:String x:Key="Help">HELP</sys:String>
<sys:String x:Key="HelpFan">HELP</sys:String> <sys:String x:Key="HelpFan">HELP</sys:String>
<sys:String x:Key="NameType">NAME</sys:String> <sys:String x:Key="NameType">NAME</sys:String>
@ -16,18 +16,18 @@
<sys:String x:Key="DetectionResult">Detection Result</sys:String> <sys:String x:Key="DetectionResult">Detection Result</sys:String>
<sys:String x:Key="StartDetection">Starting detection, please wait...</sys:String> <sys:String x:Key="StartDetection">Starting detection, please wait...</sys:String>
<sys:String x:Key="ImportModel">Import Template</sys:String> <sys:String x:Key="ImportModel">Import</sys:String>
<sys:String x:Key="Save">Update and Save</sys:String> <sys:String x:Key="Save">Update</sys:String>
<sys:String x:Key="AddRow">Add Row</sys:String> <sys:String x:Key="AddRow">Add</sys:String>
<sys:String x:Key="AlgorithmConfig">Algorithm Configuration</sys:String> <sys:String x:Key="AlgorithmConfig">Algorithm</sys:String>
<sys:String x:Key="LevelConfig">Grading Configuration</sys:String> <sys:String x:Key="LevelConfig">Grading</sys:String>
<sys:String x:Key="CutConfig">Cutting Tool Configuration</sys:String> <sys:String x:Key="CutConfig">Cut Machine</sys:String>
<sys:String x:Key="NoPassword">Username or password incorrect, please try again</sys:String> <sys:String x:Key="NoPassword">Username or password incorrect, please try again</sys:String>
<sys:String x:Key="DeleteConfig">Delete Configuration</sys:String> <sys:String x:Key="DeleteConfig">Delete</sys:String>
<sys:String x:Key="ImportConfig">Import Configuration</sys:String> <sys:String x:Key="ImportConfig">Import</sys:String>
<sys:String x:Key="BeautifyJson">Beautify Json</sys:String> <sys:String x:Key="BeautifyJson">Beautify</sys:String>
<sys:String x:Key="UglifyJson">Compress Json</sys:String> <sys:String x:Key="UglifyJson">Compress</sys:String>
<sys:String x:Key="ExitAsk">Do you want to exit the program?</sys:String> <sys:String x:Key="ExitAsk">Do you want to exit the program?</sys:String>
@ -35,19 +35,19 @@
<sys:String x:Key="Yes">Yes</sys:String> <sys:String x:Key="Yes">Yes</sys:String>
<sys:String x:Key="No">No</sys:String> <sys:String x:Key="No">No</sys:String>
<sys:String x:Key="Cancel">Cancel</sys:String> <sys:String x:Key="Cancel">Cancel</sys:String>
<sys:String x:Key="Confirm">Confirm</sys:String> <sys:String x:Key="Confirm">OK</sys:String>
<!-- Grading Configuration Screen --> <!-- Grading Configuration Screen -->
<sys:String x:Key="Save_successful_message">Data saved successfully</sys:String> <sys:String x:Key="Save_successful_message">Data saved successfully</sys:String>
<sys:String x:Key="save_fail_message">Data save failed</sys:String> <sys:String x:Key="save_fail_message">Data save failed</sys:String>
<sys:String x:Key="no_data_message">No data imported</sys:String> <sys:String x:Key="no_data_message">No data imported</sys:String>
<sys:String x:Key="grade_config_left_top">Parameters \\ Cutting Grade</sys:String> <sys:String x:Key="grade_config_left_top">Parameters \ Cutting Grade</sys:String>
<sys:String x:Key="GRADE_NAME">GRADE_NAME</sys:String> <sys:String x:Key="GRADE_NAME">GRADE_EN_NAME</sys:String>
<sys:String x:Key="STANDARD_NAME">STANDARD_NAME</sys:String> <sys:String x:Key="STANDARD_NAME">STANDARD_EN_NAME</sys:String>
<sys:String x:Key="SHAPE_NAME">SHAPE_NAME</sys:String> <sys:String x:Key="SHAPE_NAME">SHAPE_EN_NAME</sys:String>
<sys:String x:Key="INSTITUTE_NAME">INSTITUTE_NAME</sys:String> <sys:String x:Key="INSTITUTE_NAME">INSTITUTE_EN_NAME</sys:String>
<sys:String x:Key="RULE_NAME">RULE_NAME</sys:String> <sys:String x:Key="RULE_NAME">RULE_EN_NAME</sys:String>
<!-- Start Detection Button Popup--> <!-- Start Detection Button Popup-->
<sys:String x:Key="UpdateDiamondCode">Please enter the diamond code to upload</sys:String> <sys:String x:Key="UpdateDiamondCode">Please enter the diamond code</sys:String>
<sys:String x:Key="ok">OK</sys:String> <sys:String x:Key="ok">OK</sys:String>
<sys:String x:Key="Skip">Skip</sys:String> <sys:String x:Key="Skip">Skip</sys:String>
<sys:String x:Key="NoDiamondCode">No diamond code entered</sys:String> <sys:String x:Key="NoDiamondCode">No diamond code entered</sys:String>
@ -90,10 +90,10 @@
<sys:String x:Key="SavePathIsnotExists">Save path does not exist</sys:String> <sys:String x:Key="SavePathIsnotExists">Save path does not exist</sys:String>
<!-- System Configuration Multilingual --> <!-- System Configuration Multilingual -->
<sys:String x:Key="SystemSetting">System Settings</sys:String> <sys:String x:Key="SystemSetting">System</sys:String>
<sys:String x:Key="SystemSettingCustomSet">General Settings</sys:String> <sys:String x:Key="SystemSettingCustomSet">General</sys:String>
<sys:String x:Key="SystemSettingModelSet">Model Settings</sys:String> <sys:String x:Key="SystemSettingModelSet">Model</sys:String>
<sys:String x:Key="SystemSettingSave">Save/Save</sys:String> <sys:String x:Key="SystemSettingSave">Save</sys:String>
<sys:String x:Key="SystemSettingCustomSetLanguageSet">Language Settings</sys:String> <sys:String x:Key="SystemSettingCustomSetLanguageSet">Language Settings</sys:String>
<sys:String x:Key="SystemSettingCustomSetUploadFileSet">Upload Files</sys:String> <sys:String x:Key="SystemSettingCustomSetUploadFileSet">Upload Files</sys:String>
<sys:String x:Key="SystemSettingCustomSetUploadFileText">TXT Files</sys:String> <sys:String x:Key="SystemSettingCustomSetUploadFileText">TXT Files</sys:String>
@ -125,7 +125,7 @@
<sys:String x:Key="SystemSettingModelSetLowerGirdleColor">Lower Girdle Color</sys:String> <sys:String x:Key="SystemSettingModelSetLowerGirdleColor">Lower Girdle Color</sys:String>
<sys:String x:Key="SystemSettingModelSetCuletColor">Culet Color</sys:String> <sys:String x:Key="SystemSettingModelSetCuletColor">Culet Color</sys:String>
<!-- Dialog Default Language --> <!-- Dialog Default Language -->
<sys:String x:Key="DialogConfirmDefaultTitle">Confirm</sys:String> <sys:String x:Key="DialogConfirmDefaultTitle">OK</sys:String>
<sys:String x:Key="DialogCancelDefaultTitle">Cancel</sys:String> <sys:String x:Key="DialogCancelDefaultTitle">Cancel</sys:String>
@ -144,20 +144,21 @@
<sys:String x:Key="ViewportRightMenuSelectFaceKind">Show Similar Faces</sys:String> <sys:String x:Key="ViewportRightMenuSelectFaceKind">Show Similar Faces</sys:String>
<sys:String x:Key="ViewportRightMenuShowDefectFace">Show Defective Faces</sys:String> <sys:String x:Key="ViewportRightMenuShowDefectFace">Show Defective Faces</sys:String>
<sys:String x:Key="ViewportRightMenuShowFront">Show Positive Direction Mark</sys:String> <sys:String x:Key="ViewportRightMenuShowFront">Show Positive Direction Mark</sys:String>
<sys:String x:Key="ViewportRightMenuShowMeshLines">Show grid lines</sys:String>
<sys:String x:Key="ViewportSaveSucceed">Save Successful</sys:String> <sys:String x:Key="ViewportSaveSucceed">Save Successful</sys:String>
<sys:String x:Key="ViewportSaveFail">Save Failed</sys:String> <sys:String x:Key="ViewportSaveFail">Save Failed</sys:String>
<sys:String x:Key="ViewportSelectPath">Select Path</sys:String> <sys:String x:Key="ViewportSelectPath">Select Path</sys:String>
<!-- Login Page --> <!-- Login Page -->
<sys:String x:Key="LoginWindowTitle">Spark Diamond Detection System</sys:String> <sys:String x:Key="LoginWindowTitle">SparkDetectionSystem</sys:String>
<sys:String x:Key="LoginWindowAccount">Account</sys:String> <sys:String x:Key="LoginWindowAccount">Account</sys:String>
<sys:String x:Key="LoginWindowPassword">Password</sys:String> <sys:String x:Key="LoginWindowPassword">Password</sys:String>
<sys:String x:Key="LoginWindowRemember">Remember Password</sys:String> <sys:String x:Key="LoginWindowRemember">Remember Password</sys:String>
<sys:String x:Key="LoginWindowLogin">Login</sys:String> <sys:String x:Key="LoginWindowLogin">Login</sys:String>
<sys:String x:Key="LoginWindowExit">Exit System</sys:String> <sys:String x:Key="LoginWindowExit">Exit System</sys:String>
<sys:String x:Key="LoginWindowForgot">If you forgot your password, please contact us</sys:String> <sys:String x:Key="LoginWindowForgot">Forgot password, please contact the administrator</sys:String>
<!-- New Detection Results --> <!-- New Detection Results -->
<sys:String x:Key="DiamondResultSave">Save</sys:String> <sys:String x:Key="DiamondResultSave">Save</sys:String>
<sys:String x:Key="DiamondResultExport">Export</sys:String> <sys:String x:Key="DiamondResultExport">Export</sys:String>
<sys:String x:Key="DiamondResultDs">DS</sys:String> <sys:String x:Key="DiamondResultDs">DS</sys:String>
@ -168,16 +169,16 @@
<sys:String x:Key="DiamondResultWeight">Weight (ct)</sys:String> <sys:String x:Key="DiamondResultWeight">Weight (ct)</sys:String>
<sys:String x:Key="DiamondResultCutGrade">Cut Grade</sys:String> <sys:String x:Key="DiamondResultCutGrade">Cut Grade</sys:String>
<sys:String x:Key="DiamondResultSymmetryGrade">Symmetry Grade</sys:String> <sys:String x:Key="DiamondResultSymmetryGrade">Symmetry Grade</sys:String>
<sys:String x:Key="DiamondResultGridAvgValue">Average</sys:String> <sys:String x:Key="DiamondResultGridAvgValue">Avg</sys:String>
<sys:String x:Key="DiamondResultGridDeviationValue">Deviation</sys:String> <sys:String x:Key="DiamondResultGridDeviationValue">Dev</sys:String>
<sys:String x:Key="DiamondResultGridMaxValue">Max Value</sys:String> <sys:String x:Key="DiamondResultGridMaxValue">Max</sys:String>
<sys:String x:Key="DiamondResultGridMinValue">Min Value</sys:String> <sys:String x:Key="DiamondResultGridMinValue">Min</sys:String>
<sys:String x:Key="DiamondResultGridCutLevel">Cut Level</sys:String> <sys:String x:Key="DiamondResultGridCutLevel">Cut Grade</sys:String>
<sys:String x:Key="DiamondResultGridSymLevel">SYM Level</sys:String> <sys:String x:Key="DiamondResultGridSymLevel">SYM Grade</sys:String>
<sys:String x:Key="DiamondResultPopupFacet1">Facet 1</sys:String> <sys:String x:Key="DiamondResultPopupFacet1">Facet 1</sys:String>
<sys:String x:Key="DiamodResultCloseConfirm">Are you sure you want to close the detection results screen?</sys:String> <sys:String x:Key="DiamodResultCloseConfirm">Are you sure you want to close the detection results screen?</sys:String>
<!-- External Interface Messages--> <!-- External Interface Messages-->
<sys:String x:Key="InProgress">S001: Image capture in progress</sys:String> <sys:String x:Key="InProgress">S001: Image capture in progress</sys:String>
<sys:String x:Key="CacheCleared">S002: Cache image cleared</sys:String> <sys:String x:Key="CacheCleared">S002: Cache image cleared</sys:String>
<sys:String x:Key="CannotSendCommand">S003: Unable to send command to microcontroller</sys:String> <sys:String x:Key="CannotSendCommand">S003: Unable to send command to microcontroller</sys:String>
@ -197,5 +198,5 @@
<sys:String x:Key="CUDANoInstall">CUDA not installed, program may encounter errors during execution</sys:String> <sys:String x:Key="CUDANoInstall">CUDA not installed, program may encounter errors during execution</sys:String>
<sys:String x:Key="MSVCRuntimeNoInstall">MSVC Runtime not installed, program may encounter errors during execution</sys:String> <sys:String x:Key="MSVCRuntimeNoInstall">MSVC Runtime not installed, program may encounter errors during execution</sys:String>
<sys:String x:Key="FilePathNotExists">File path does not exist</sys:String> <sys:String x:Key="FilePathNotExists">File path does not exist</sys:String>
<sys:String x:Key="LevelConfigFormatError">The file format is incorrect</sys:String>
</ResourceDictionary> </ResourceDictionary>

@ -24,7 +24,6 @@
<sys:String x:Key="LevelConfig">定级配置</sys:String> <sys:String x:Key="LevelConfig">定级配置</sys:String>
<sys:String x:Key="CutConfig">切工仪配置</sys:String> <sys:String x:Key="CutConfig">切工仪配置</sys:String>
<sys:String x:Key="NoPassword">用户名或密码错误,请重试</sys:String> <sys:String x:Key="NoPassword">用户名或密码错误,请重试</sys:String>
<!-- <sys:String x:Key="LevelConfig">定级配置</sys:String> -->
<sys:String x:Key="DeleteConfig">删除配置</sys:String> <sys:String x:Key="DeleteConfig">删除配置</sys:String>
<sys:String x:Key="ImportConfig">导入配置</sys:String> <sys:String x:Key="ImportConfig">导入配置</sys:String>
<sys:String x:Key="BeautifyJson">美化Json</sys:String> <sys:String x:Key="BeautifyJson">美化Json</sys:String>
@ -41,14 +40,14 @@
<sys:String x:Key="Save_successful_message">数据保存成功</sys:String> <sys:String x:Key="Save_successful_message">数据保存成功</sys:String>
<sys:String x:Key="save_fail_message">数据保存失败</sys:String> <sys:String x:Key="save_fail_message">数据保存失败</sys:String>
<sys:String x:Key="no_data_message">没有导入数据</sys:String> <sys:String x:Key="no_data_message">没有导入数据</sys:String>
<sys:String x:Key="grade_config_left_top">参数 \\ 切工等级</sys:String> <sys:String x:Key="grade_config_left_top">参数 \ 切工等级</sys:String>
<sys:String x:Key="GRADE_NAME">GRADE_NAME</sys:String> <sys:String x:Key="GRADE_NAME">GRADE_NAME</sys:String>
<sys:String x:Key="STANDARD_NAME">STANDARD_NAME</sys:String> <sys:String x:Key="STANDARD_NAME">STANDARD_NAME</sys:String>
<sys:String x:Key="SHAPE_NAME">SHAPE_NAME</sys:String> <sys:String x:Key="SHAPE_NAME">SHAPE_NAME</sys:String>
<sys:String x:Key="INSTITUTE_NAME">INSTITUTE_NAME</sys:String> <sys:String x:Key="INSTITUTE_NAME">INSTITUTE_NAME</sys:String>
<sys:String x:Key="RULE_NAME">RULE_NAME</sys:String> <sys:String x:Key="RULE_NAME">RULE_NAME</sys:String>
<!-- 开始检测按钮点击后弹窗--> <!-- 开始检测按钮点击后弹窗-->
<sys:String x:Key="UpdateDiamondCode">请输入上传钻石编码</sys:String> <sys:String x:Key="UpdateDiamondCode">请输入钻石编码</sys:String>
<sys:String x:Key="ok">确定</sys:String> <sys:String x:Key="ok">确定</sys:String>
<sys:String x:Key="Skip">跳过</sys:String> <sys:String x:Key="Skip">跳过</sys:String>
<sys:String x:Key="NoDiamondCode">没有输入钻石编码</sys:String> <sys:String x:Key="NoDiamondCode">没有输入钻石编码</sys:String>
@ -179,7 +178,7 @@
<sys:String x:Key="DiamondResultPopupFacet1">面1</sys:String> <sys:String x:Key="DiamondResultPopupFacet1">面1</sys:String>
<sys:String x:Key="DiamodResultCloseConfirm">是否关闭检测结果画面。</sys:String> <sys:String x:Key="DiamodResultCloseConfirm">是否关闭检测结果画面。</sys:String>
<!-- 外部接口MSG--> <!-- 外部接口MSG-->
<sys:String x:Key="InProgress">S001:采图正在进行中</sys:String> <sys:String x:Key="InProgress">S001:采图正在进行中</sys:String>
<sys:String x:Key="CacheCleared">S002:缓存图片被清理</sys:String> <sys:String x:Key="CacheCleared">S002:缓存图片被清理</sys:String>
<sys:String x:Key="CannotSendCommand">S003:无法向单片机发送指令</sys:String> <sys:String x:Key="CannotSendCommand">S003:无法向单片机发送指令</sys:String>
@ -194,10 +193,10 @@
<sys:String x:Key="NoDiamond">P011:未检测到钻石</sys:String> <sys:String x:Key="NoDiamond">P011:未检测到钻石</sys:String>
<sys:String x:Key="OpenOfTheHatch">S007:请检查切工仪设备舱门是否关闭</sys:String> <sys:String x:Key="OpenOfTheHatch">S007:请检查切工仪设备舱门是否关闭</sys:String>
<sys:String x:Key="ApplicationError">应用程序出现错误:</sys:String> <sys:String x:Key="ApplicationError">应用程序出现错误:</sys:String>
<sys:String x:Key="CUDANoInstall">CUDA未安装,程序执行中可能会出错</sys:String> <sys:String x:Key="CUDANoInstall">CUDA未安装,程序执行中可能会出错</sys:String>
<sys:String x:Key="MSVCRuntimeNoInstall">MSVC Runtime未安装,程序执行中可能会出错</sys:String> <sys:String x:Key="MSVCRuntimeNoInstall">MSVC Runtime未安装,程序执行中可能会出错</sys:String>
<sys:String x:Key="FilePathNotExists">文件路径不存在</sys:String> <sys:String x:Key="FilePathNotExists">文件路径不存在</sys:String>
<sys:String x:Key="LevelConfigFormatError">定级配置文件格式不正</sys:String> <sys:String x:Key="LevelConfigFormatError">文件格式不正</sys:String>
</ResourceDictionary> </ResourceDictionary>

@ -413,12 +413,14 @@ public partial class Viewport3D
ViewportManager.ResetChooseAddModels(); ViewportManager.ResetChooseAddModels();
break; break;
case "ViewportRightMenuShowMeshLines": case "ViewportRightMenuShowMeshLines":
var center = ViewportManager.ModelBounds.Center;
var maxDimension = ViewportManager.ModelBounds.Size.Length(); var maxDimension = ViewportManager.ModelBounds.Size.Length();
var distance = maxDimension * 1.2; // 调整相机到模型的距离,保证视野范围内 var distance = maxDimension * 1.2; // 调整相机到模型的距离,保证视野范围内
var center = ViewportManager.ModelBounds.Center; // 获取当前相机
var camera = Viewport3Dx.Camera as HelixToolkit.Wpf.SharpDX.PerspectiveCamera; var camera = Viewport3Dx.Camera as HelixToolkit.Wpf.SharpDX.PerspectiveCamera;
camera.Position = new Point3D(center.X, center.Y - distance, center.Z); // 从底部看,Y轴负方向 camera.Position = new Point3D(center.X, center.Y - distance, center.Z); // 从底部看,Y轴负方向
camera.UpDirection = new Vector3D(0, 0, -1); 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); ViewportManager.ShowMeshLines(checkResult);
//camera.LookDirection = new Vector3D(center.X - camera.Position.X, center.Y - camera.Position.Y, center.Z - camera.Position.Z); //camera.LookDirection = new Vector3D(center.X - camera.Position.X, center.Y - camera.Position.Y, center.Z - camera.Position.Z);

@ -12,7 +12,7 @@ namespace SparkClient.Views.UserControl.ViewportData.Helper
{ {
private readonly float Y = -0.01F; private readonly float Y = -0.01F;
private Vector3 point1; private Vector3 point1;
private Vector3 point2; private Vector3 center;
/// <summary> /// <summary>
/// 常数a(y=ax+b) /// 常数a(y=ax+b)
/// </summary> /// </summary>
@ -21,21 +21,21 @@ namespace SparkClient.Views.UserControl.ViewportData.Helper
/// 常数b(y=ax+b) /// 常数b(y=ax+b)
/// </summary> /// </summary>
private float b; private float b;
public LineCalculationHelper(Vector3 point1, Vector3 point2) { public LineCalculationHelper(Vector3 point1, Vector3 center) {
this.point1 = point1; this.point1 = point1;
this.point2 = point2; this.center = center;
this.a = calA(point1, point2); this.a = calA(point1, center);
this.b = calB(point1, a); this.b = calB(point1, a);
} }
/// <summary> /// <summary>
/// 常数a的计算 /// 常数a的计算
/// </summary> /// </summary>
/// <param name="point1"></param> /// <param name="point1"></param>
/// <param name="point2"></param> /// <param name="center"></param>
/// <returns></returns> /// <returns></returns>
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);
} }
/// <summary> /// <summary>
/// 常数b的计算 /// 常数b的计算
@ -50,18 +50,20 @@ namespace SparkClient.Views.UserControl.ViewportData.Helper
public Tuple<Vector3, Vector3> calXline(float length) public Tuple<Vector3, Vector3> calXline(float length)
{ {
var x1 = 5; var twoPoint = CalculatePointsOnLine(this.a,length);
var z1 = calZ(x1); var x1 = twoPoint.p1.X;
var x2 = -5; var z1 = twoPoint.p1.Y;
var z2 = calZ(x2); var x2 = twoPoint.p2.X;
var z2 = twoPoint.p2.X;
return new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)); return new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2));
} }
public Tuple<Vector3, Vector3> calYline(float length) public Tuple<Vector3, Vector3> calYline(float length)
{ {
var x1 = 5; var twoPoint = CalculatePointsOnLine(-(1/a), length);
var z1 = calZVertical(x1); var x1 = twoPoint.p1.X;
var x2 = -5; var z1 = twoPoint.p1.Y;
var z2 = calZVertical(x2); var x2 = twoPoint.p2.X;
var z2 = twoPoint.p2.X;
return new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)); return new Tuple<Vector3, Vector3>(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; 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);
}
} }
} }

@ -1273,6 +1273,12 @@ public class ViewportHelperPro
lights.ForEach(item => viewport.Items.Remove(item)); lights.ForEach(item => viewport.Items.Remove(item));
} }
private static Dictionary<Guid, Guid> moveLines = new Dictionary<Guid, Guid>(); private static Dictionary<Guid, Guid> moveLines = new Dictionary<Guid, Guid>();
/// <summary>
/// 网状参考线
/// </summary>
/// <param name="entities"></param>
/// <param name="thickness"></param>
/// <returns></returns>
public static List<LineGeometryModel3D> ShowMeshLines(List<Viewport3DTriangleEntity> entities, double thickness = 1.0) public static List<LineGeometryModel3D> ShowMeshLines(List<Viewport3DTriangleEntity> entities, double thickness = 1.0)
{ {
moveLines = new(); moveLines = new();
@ -1288,9 +1294,14 @@ public class ViewportHelperPro
var edgeLines = new List<Tuple<Vector3, Vector3>>(); var edgeLines = new List<Tuple<Vector3, Vector3>>();
Color4 XlineColor =new Color4(80f, 0f, 0f, 1f); 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 z1 = lineCal.calZ(x1);
var x2 = -5; var x2 = -r;
var z2 = lineCal.calZ(x2); var z2 = lineCal.calZ(x2);
edgeLines.Add(new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2))); edgeLines.Add(new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)));
lines.Add(DisplayLineModel3D(edgeLines, XlineColor)); lines.Add(DisplayLineModel3D(edgeLines, XlineColor));
@ -1318,9 +1329,9 @@ public class ViewportHelperPro
bindingMoveLine(lineE, lineF); bindingMoveLine(lineE, lineF);
Color4 YlineColor = new Color4(0F, 80f, 0f, 1f); Color4 YlineColor = new Color4(0F, 80f, 0f, 1f);
var x3 = 5; var x3 = r;
var z3 = lineCal.calZVertical(x3); var z3 = lineCal.calZVertical(x3);
var x4 = -5; var x4 = -r;
var z4 = lineCal.calZVertical(x4); var z4 = lineCal.calZVertical(x4);
edgeLines = new List<Tuple<Vector3, Vector3>>(); edgeLines = new List<Tuple<Vector3, Vector3>>();
@ -1350,7 +1361,11 @@ public class ViewportHelperPro
bindingMoveLine(lineG, lineH); bindingMoveLine(lineG, lineH);
return lines; return lines;
} }
/// <summary>
/// 网状参考线 对向移动绑定
/// </summary>
/// <param name="lineA"></param>
/// <param name="lineB"></param>
private static void bindingMoveLine(LineGeometryModel3D lineA, LineGeometryModel3D lineB) private static void bindingMoveLine(LineGeometryModel3D lineA, LineGeometryModel3D lineB)
{ {
lineA.MouseDown3D += LineA_MouseDown3D; lineA.MouseDown3D += LineA_MouseDown3D;
@ -1386,7 +1401,7 @@ public class ViewportHelperPro
var perpendicularDirection = Vector3D.CrossProduct(lineDirection.ToVector3D(), Vector3D.CrossProduct(moveDirection, lineDirection.ToVector3D())); var perpendicularDirection = Vector3D.CrossProduct(lineDirection.ToVector3D(), Vector3D.CrossProduct(moveDirection, lineDirection.ToVector3D()));
perpendicularDirection.Normalize(); perpendicularDirection.Normalize();
double scaleFactor = 0.1; // 缩放因子 double scaleFactor = 0.05; // 缩放因子
// 计算垂直距离 // 计算垂直距离
double perpendicularDistance = Vector3D.DotProduct(moveDirection, perpendicularDirection) * scaleFactor; double perpendicularDistance = Vector3D.DotProduct(moveDirection, perpendicularDirection) * scaleFactor;
System.Console.WriteLine("距离:"+ perpendicularDistance); System.Console.WriteLine("距离:"+ perpendicularDistance);
@ -1436,11 +1451,11 @@ public class ViewportHelperPro
// 创建射线 // 创建射线
var ray = new Ray3D( var ray = new Ray3D(
camera.Position, 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) // 创建平面(假设平面为 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); var intersection = GetIntersection(ray, plane);
@ -1456,13 +1471,23 @@ public class ViewportHelperPro
// 使用 Plane3D.LineIntersection 方法计算交点 // 使用 Plane3D.LineIntersection 方法计算交点
return plane.LineIntersection(ray.Origin, rayEnd); 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>
/// <param name="radius"></param>
/// <param name="thickness"></param>
/// <returns></returns>
public static LineGeometryModel3D ShowCircleLine(double radius = 1.0, double thickness = 1.0) public static LineGeometryModel3D ShowCircleLine(double radius = 1.0, double thickness = 1.0)
{ {
var Y = -0.01F; var Y = -0.01F;
var center = ViewportManager.CenterVector; var center = ViewportManager.CenterVector;
center.Y = Y; center.Y = Y;
return UpdateCircleGeometry(center); return UpdateCircleGeometry(center, initialRadius);
} }
private static LineGeometryModel3D UpdateCircleGeometry(Vector3 center, double radius = 1.0) private static LineGeometryModel3D UpdateCircleGeometry(Vector3 center, double radius = 1.0)
{ {
@ -1482,11 +1507,106 @@ public class ViewportHelperPro
indices.Add(i); indices.Add(i);
indices.Add((i + 1) % segments); 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 私有方法 #region 私有方法
/// <summary> /// <summary>

@ -278,6 +278,7 @@ public class ViewportManager
_viewport.Camera.UpDirection = new Vector3D(0, -1, 0); _viewport.Camera.UpDirection = new Vector3D(0, -1, 0);
_viewport.RenderHost.MSAA = MSAALevel.Maximum; _viewport.RenderHost.MSAA = MSAALevel.Maximum;
// TODO: // TODO:
MainModelMeshLines.Clear();
MainModelMeshLines.AddRange(ViewportHelperPro.ShowMeshLines(entities)); MainModelMeshLines.AddRange(ViewportHelperPro.ShowMeshLines(entities));
MainModelCircleLine = ViewportHelperPro.ShowCircleLine(); MainModelCircleLine = ViewportHelperPro.ShowCircleLine();
} }

Loading…
Cancel
Save