|
|
|
@ -1399,6 +1399,7 @@ public class ViewportHelperPro |
|
|
|
|
} |
|
|
|
|
private static bool isDrawing = false; |
|
|
|
|
private static Point3D previousMousePosition; |
|
|
|
|
private static bool isOutOfRange = false; |
|
|
|
|
|
|
|
|
|
private static void LineA_MouseMove3D(object sender, RoutedEventArgs e) |
|
|
|
|
{ |
|
|
|
@ -1406,6 +1407,20 @@ public class ViewportHelperPro |
|
|
|
|
{ |
|
|
|
|
if (e is HelixToolkit.Wpf.SharpDX.MouseMove3DEventArgs ev) |
|
|
|
|
{ |
|
|
|
|
// 定义中心点和半径 |
|
|
|
|
var Y = -0.01F; |
|
|
|
|
if (!IsCrown()) |
|
|
|
|
{ |
|
|
|
|
Y = ViewportManager.ModelBounds.Maximum.Y + 0.01f; |
|
|
|
|
} |
|
|
|
|
var center = ViewportManager.CenterVector; |
|
|
|
|
center.Y = Y; |
|
|
|
|
double radius = 5; |
|
|
|
|
if (double.TryParse(ViewportManager.DiamondData["M2"].ToString(), out var v)) |
|
|
|
|
{ |
|
|
|
|
radius = (v * 0.5); |
|
|
|
|
} |
|
|
|
|
double minDistance = 0.01; // 最小距离 |
|
|
|
|
var line = sender as LineGeometryModel3D; |
|
|
|
|
// 直线方向分量 |
|
|
|
|
var lineDirection = line.Geometry.Positions[1] - line.Geometry.Positions[0]; |
|
|
|
@ -1421,31 +1436,120 @@ public class ViewportHelperPro |
|
|
|
|
var perpendicularDirection = Vector3D.CrossProduct(lineDirection.ToVector3D(), Vector3D.CrossProduct(moveDirection, lineDirection.ToVector3D())); |
|
|
|
|
perpendicularDirection.Normalize(); |
|
|
|
|
|
|
|
|
|
double scaleFactor = 0.05; // 缩放因子 |
|
|
|
|
double scaleFactor = 13000; // 缩放因子 |
|
|
|
|
// 计算垂直距离 |
|
|
|
|
double perpendicularDistance = Vector3D.DotProduct(moveDirection, perpendicularDirection) * scaleFactor; |
|
|
|
|
System.Console.WriteLine("距离:"+ perpendicularDistance); |
|
|
|
|
// 垂直方向偏移量 |
|
|
|
|
Vector3D projectedVector = perpendicularDistance * perpendicularDirection; |
|
|
|
|
projectedVector.Y = 0; |
|
|
|
|
|
|
|
|
|
// 计算直线的新位置 |
|
|
|
|
var transform = new TranslateTransform3D(projectedVector); |
|
|
|
|
var newPosition1 = line.Geometry.Positions[0].ToVector3D() + projectedVector; |
|
|
|
|
var newPosition2 = line.Geometry.Positions[1].ToVector3D() + projectedVector; |
|
|
|
|
|
|
|
|
|
// 计算直线的新中心点 |
|
|
|
|
Point3D newCenter = new Point3D( |
|
|
|
|
(newPosition1.X + newPosition2.X) / 2, |
|
|
|
|
(newPosition1.Y + newPosition2.Y) / 2, |
|
|
|
|
(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, |
|
|
|
|
(line.Geometry.Positions[0].Y + line.Geometry.Positions[1].Y) / 2, |
|
|
|
|
(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) |
|
|
|
|
{ |
|
|
|
|
//// 如果新中心点不满足条件,将位置限制在范围内 |
|
|
|
|
//projectedVector = LimitToRange(newCenter, center.ToPoint3D(), radius, minDistance) - newCenter; |
|
|
|
|
// 如果新中心点超出范围,将直线位置固定到最大允许位置 |
|
|
|
|
Point3D maxCenter = LimitToMaxPosition(center.ToPoint3D(), radius, newCenter); |
|
|
|
|
// 计算直线的起点和终点在最大允许位置 |
|
|
|
|
projectedVector = maxCenter - previousCenter; |
|
|
|
|
projectedVector.Y = 0; |
|
|
|
|
transform = new TranslateTransform3D(projectedVector); |
|
|
|
|
//Logger.Info($"X:{projectedVector.X},Z:{projectedVector.Z}"); |
|
|
|
|
Logger.Info("超出范围,停止移动"); |
|
|
|
|
}else if(!isMovingAway) |
|
|
|
|
{ |
|
|
|
|
isOutOfRange = true; |
|
|
|
|
Logger.Info("isOutOfRange = true;"); |
|
|
|
|
} |
|
|
|
|
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 ) |
|
|
|
|
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); |
|
|
|
|
var transform_other = new TranslateTransform3D(-projectedVector); |
|
|
|
|
otherLine.Transform = transform_other; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// 检查点是否在范围内(距离大于 minDistance 且小于等于 radius) |
|
|
|
|
private static bool IsPointInRange(Point3D point, Point3D center, double radius, double minDistance) |
|
|
|
|
{ |
|
|
|
|
double distance = (point - center).Length; |
|
|
|
|
Logger.Info("距离:" + distance); |
|
|
|
|
return distance > minDistance && distance <= radius; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static Point3D LimitToMaxPosition(Point3D center, double radius, Point3D currentCenter) |
|
|
|
|
{ |
|
|
|
|
// 计算当前中心点与中心点的方向 |
|
|
|
|
Vector3D direction = currentCenter - center; |
|
|
|
|
direction.Normalize(); |
|
|
|
|
|
|
|
|
|
// 计算最大允许位置 |
|
|
|
|
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) |
|
|
|
@ -1470,13 +1574,9 @@ public class ViewportHelperPro |
|
|
|
|
{ |
|
|
|
|
// 使用 HelixToolkit 的 Ray3D 和 Plane3D |
|
|
|
|
var Viewport = ViewportManager.GetViewport3D(); |
|
|
|
|
var camera = Viewport.Camera as OrthographicCamera; |
|
|
|
|
|
|
|
|
|
// 创建射线 |
|
|
|
|
var ray = new Ray3D( |
|
|
|
|
camera.Position, |
|
|
|
|
new Vector3D(mousePosition.X - Viewport.ActualWidth / 2, -camera.Position.Y, -(mousePosition.Y - Viewport.ActualHeight / 2) ) |
|
|
|
|
); |
|
|
|
|
// 获取射线 |
|
|
|
|
var ray = GetRayFromMouse(mousePosition, Viewport); |
|
|
|
|
|
|
|
|
|
// 创建平面(假设平面为 Y=0) |
|
|
|
|
var plane = new Plane3D(new Point3D(0, 0, 0), new Vector3D(0, 1, 0)); |
|
|
|
@ -1484,9 +1584,49 @@ public class ViewportHelperPro |
|
|
|
|
// 计算射线与平面的交点 |
|
|
|
|
var intersection = GetIntersection(ray, plane); |
|
|
|
|
|
|
|
|
|
return intersection ?? new Point3D(0, 0, 0); |
|
|
|
|
if (intersection == null) |
|
|
|
|
{ |
|
|
|
|
// 如果没有交点,返回默认值或抛出异常 |
|
|
|
|
throw new InvalidOperationException("No intersection found."); |
|
|
|
|
} |
|
|
|
|
return intersection.Value; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static Ray3D GetRayFromMouse(Point mousePosition, Viewport3DX viewport) |
|
|
|
|
{ |
|
|
|
|
// 将鼠标坐标转换为归一化设备坐标 (NDC) |
|
|
|
|
var ndc = new Vector2( |
|
|
|
|
(float)(2.0 * mousePosition.X / viewport.ActualWidth - 1.0), |
|
|
|
|
(float)(1.0 - 2.0 * mousePosition.Y / viewport.ActualHeight) |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
// 使用 UnProject 方法获取射线 |
|
|
|
|
var ray = viewport.UnProject(ndc); |
|
|
|
|
|
|
|
|
|
// 返回射线 |
|
|
|
|
return new Ray3D(ray.Position.ToPoint3D(), ray.Direction.ToPoint3D()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//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; |
|
|
|
|
|
|
|
|
|
// // 计算射线起点到平面的距离 |
|
|
|
|
// double t = Vector3D.DotProduct(plane.Position - ray.Origin, plane.Normal) / denominator; |
|
|
|
|
|
|
|
|
|
// // 如果 t 为负数,说明交点在射线起点后方 |
|
|
|
|
// if (t < 0) |
|
|
|
|
// return null; |
|
|
|
|
|
|
|
|
|
// // 返回交点 |
|
|
|
|
// return ray.Origin + ray.Direction * t; |
|
|
|
|
//} |
|
|
|
|
|
|
|
|
|
private static Point3D? GetIntersection(Ray3D ray, Plane3D plane) |
|
|
|
|
{ |
|
|
|
|
// 将射线转换为直线(起点和终点) |
|
|
|
@ -1571,25 +1711,25 @@ public class ViewportHelperPro |
|
|
|
|
|
|
|
|
|
// 计算鼠标与圆心的距离 |
|
|
|
|
double distance = CalculateDistance(mouseWorldPosition, center.ToPoint3D()); |
|
|
|
|
|
|
|
|
|
Console.WriteLine($"与圆心之间距离{distance}"); |
|
|
|
|
double scaleFactor = 0; |
|
|
|
|
|
|
|
|
|
if (distance < initDistance) |
|
|
|
|
{ |
|
|
|
|
// 鼠标靠近圆心,缩小半径 |
|
|
|
|
scaleFactor = -0.01; |
|
|
|
|
scaleFactor = -1; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
// 鼠标远离圆心,扩大半径 |
|
|
|
|
scaleFactor = +0.01; |
|
|
|
|
scaleFactor = +1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 计算鼠标移动的距离(以屏幕坐标为单位) |
|
|
|
|
double delta = (dragStartPoint - mousePosition).Length; |
|
|
|
|
|
|
|
|
|
// 计算新的半径 |
|
|
|
|
double newRadius = initialRadius + delta * scaleFactor; // 缩放因子 |
|
|
|
|
double newRadius = initialRadius + (distance - initDistance)*11000; // 缩放因子 |
|
|
|
|
|
|
|
|
|
// 限制半径范围 |
|
|
|
|
newRadius = Math.Clamp(newRadius, MinRadius, MaxRadius); |
|
|
|
|