Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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));
        }
Ejemplo n.º 3
0
        /// <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);
        }
Ejemplo n.º 4
0
 public static float DistanceToLine(vec2 p, vec2 e0, vec2 e1, out float t)
 {
     return(Line2D.Distance(p, e0, e1, out t));
 }
Ejemplo n.º 5
0
        /// <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
                });
            }
        }