public override bool PointInObject(Vector2D point, ICanvasScreenConvertable canvasProxy) { if (point == null) { throw new ArgumentNullException(nameof(point)); } if (canvasProxy == null) { throw new ArgumentNullException(nameof(canvasProxy)); } if (Rectangle2D == null) { return(false); } var screenPoint = canvasProxy.ToScreen(point); //判断与中心的关系; var centerScreenPoint = canvasProxy.ToScreen(Rectangle2D.Center); var screenRect = Tida.Canvas.Infrastructure.Utils.NativeGeometryExtensions.GetNativeSuroundingScreenRect( centerScreenPoint, TolerantedScreenLength, TolerantedScreenLength ); if (screenRect.Contains(screenPoint)) { return(true); } //判断与四边的关系; var lines = Rectangle2D.GetLines(); var screenStartPoint = new Vector2D(); var screenEndPoint = new Vector2D(); foreach (var line in lines) { canvasProxy.ToScreen(line.Start, screenStartPoint); canvasProxy.ToScreen(line.End, screenEndPoint); var screenLine2D = new Line2D( screenStartPoint, screenEndPoint ); if (screenLine2D.Distance(screenPoint) < TolerantedScreenLength) { return(true); } } return(false); }
protected override ISnapShape MatchSnapShape(LineBase line, Vector2D position, ICanvasContext canvasContext) { if (!line.IsEditing) { return(null); } var screenPosition = canvasContext.CanvasProxy.ToScreen(position); /*判断关注点是否"在线段的延长线上" */ var screenLine2D = new Line2D( canvasContext.CanvasProxy.ToScreen(line.Line2D.Start), canvasContext.CanvasProxy.ToScreen(line.Line2D.End) ); //确定该点不"在"该线段上; if (screenLine2D.Distance(screenPosition) <= TolerantedScreenLength) { return(null); } /*确定该点在该线段的延长线上;*/ var projectScreenPosition = screenPosition.ProjectOn(screenLine2D); if (projectScreenPosition == null) { return(null); } if (projectScreenPosition.Distance(screenPosition) >= TolerantedScreenLength) { return(null); } //寻找距离投影点最近的一个端点作为延伸辅助线起始点; var screenStart = canvasContext.CanvasProxy.ToScreen(line.Line2D.Start); var screenEnd = canvasContext.CanvasProxy.ToScreen(line.Line2D.End); var closestPosition = screenStart.Distance(projectScreenPosition) < screenEnd.Distance(projectScreenPosition) ? line.Line2D.Start :line.Line2D.End; var projectPosition = canvasContext.CanvasProxy.ToUnit(projectScreenPosition); return(new LineSnapShape(new Line2D(closestPosition, projectPosition), projectPosition)); }
/// <summary> /// 判断画布中某个位置是否在某个线段附近; /// </summary> /// <param name="line2D"></param> /// <param name="point"></param> /// <param name="canvasProxy"></param> /// <returns></returns> public static bool PointInLine(Line2D line2D, Vector2D point, ICanvasScreenConvertable canvasProxy) { if (canvasProxy == null) { return(false); } if (line2D == null) { return(false); } //以视图单位为标准进行判断; var screenPoint = canvasProxy.ToScreen(point); var screenLine2D = new Line2D( canvasProxy.ToScreen(line2D.Start), canvasProxy.ToScreen(line2D.End) ); return(screenLine2D.Distance(screenPoint) < TolerantedScreenLength); }
public static float DistanceToLine(vec2 p, vec2 e0, vec2 e1, out float t) { return(Line2D.Distance(p, e0, e1, out t)); }
/// <summary> /// 获取某个点是否在某个线段上的辅助; /// </summary> /// <param name="line2D"></param> /// <param name="position"></param> /// <param name="canvasContext"></param> /// <returns></returns> public static ISnapShape GetOnLineSnapShape(Line2D line2D, Vector2D position, ICanvasContext canvasContext) { if (line2D == null) { throw new ArgumentNullException(nameof(line2D)); } if (position == null) { throw new ArgumentNullException(nameof(position)); } if (canvasContext == null) { throw new ArgumentNullException(nameof(canvasContext)); } var screenPosition = canvasContext.CanvasProxy.ToScreen(position); /*判断关注点是否"在线段上" */ if (line2D.Length == 0) { return(null); } var screenLine2D = new Line2D( canvasContext.CanvasProxy.ToScreen(line2D.Start), canvasContext.CanvasProxy.ToScreen(line2D.End) ); //若距离大于指定值,则无辅助点; if (screenLine2D.Distance(screenPosition) > TolerantedScreenLength) { return(null); } //若上次编辑位置为空,则根据关注点与线段的垂直距离得到一个交点; if (canvasContext.LastEditPosition == null) { return(GetVertextSnapShape(position, line2D)); } ///否则,以<see cref="canvasContext.LastEditPosition"/> ///上次编辑位置到关注点<see cref="position"/>的直线与线段的交点作为辅助点; else { //计算上次编辑到 var lastToPositionLine2D = new Line2D(canvasContext.LastEditPosition, position); var vertextPosition = lastToPositionLine2D.IntersectStraightLine(line2D); //若无交点,则可能平行,无辅助点; if (vertextPosition == null) { return(null); } //若关注点与两直线的相交点相距过远,则仍然根据关注点与线段的垂直距离得到一个交点; if (canvasContext.CanvasProxy.ToScreen(position.Distance(vertextPosition)) > TolerantedScreenLength) { return(LineSnapExtensions.GetVertextSnapShape(position, line2D)); } return(new SnapShapeForLine(vertextPosition, line2D) { Background = InLineSnapPointBackground }); } }