master
sunhonglei 5 months ago
parent c3adc5067a
commit 26dfcb0355
  1. 176
      Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs

@ -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);

Loading…
Cancel
Save