Esempio n. 1
0
        protected override DrawObject[] TrimDrawObject(Line line, DrawObjectTrimingInfo trimingInfo)
        {
            Vector2D[]   intersectPositions = trimingInfo.IntersectPositions;
            Rectangle2D2 trimArea           = trimingInfo.TrimArea;

            if (line == null)
            {
                return(null);
            }

            if (intersectPositions == null)
            {
                return(null);
            }

            if (trimArea == null)
            {
                return(null);
            }

            //将交点集合筛选(需在线段上,不包括端点),并沿线段起始到终止方向进行排序;
            intersectPositions = intersectPositions.
                                 Where(p => p.IsInLine(line.Line2D)).
                                 OrderBy(p => p.Distance(line.Line2D.Start)).
                                 ToArray();

            ///得到矩形与线段的所有交点(最多两个),通过该交点集合的与<param name="intersectPositions"/>的关系,进行裁剪;
            var rectInserserctPositions = trimArea.GetLines().
                                          Select(p => p.Intersect(line.Line2D)).
                                          Where(p => p != null).
                                          Distinct(Vector2DEqualityComparer.StaticInstance).
                                          ToArray();

            return(GetTrimedLineWithIntersectPositions(line, intersectPositions, rectInserserctPositions));
        }
Esempio n. 2
0
        public override bool ObjectInRectangle(Rectangle2D2 rect, ICanvasScreenConvertable canvasProxy, bool anyPoint)
        {
            if (rect == null)
            {
                throw new ArgumentNullException(nameof(rect));
            }

            if (Ellipse2D == null)
            {
                return(false);
            }

            //无论是否为任意选中,若包含了,则能够选中;
            if (rect.Contains(Ellipse2D.Center) && rect.GetLines().All(p => p.Distance(Ellipse2D.Center) >= Ellipse2D.RadiusX))
            {
                return(true);
            }


            //若为任意点选中,矩形的四个顶点中,存在任意两点任意一点在椭圆内即可;
            if (anyPoint && rect.GetLines().Any(p => {
                var intersectPoints = Extension.IntersectWithLine(Ellipse2D, p);
                return((intersectPoints?.Length ?? 0) != 0);
            }))
            {
                return(rect.GetVertexes().Any(p => Ellipse2D.Contains(p)));
            }


            return(false);
        }
Esempio n. 3
0
 public Rectangle(Rectangle2D2 rectangle2D)
 {
     if (rectangle2D == null)
     {
         throw new ArgumentNullException(nameof(rectangle2D));
     }
     this.Rectangle2D = rectangle2D;
 }
Esempio n. 4
0
        /// <summary>
        /// 绘制矩形;
        /// </summary>
        /// <param name="brush">填充颜色</param>
        /// <param name="pen"></param>
        /// <param name="rectangle"></param>
        public void DrawRectangle(Rectangle2D2 rectangle, Brush brush, Pen pen)
        {
            if (rectangle == null)
            {
                throw new ArgumentNullException(nameof(rectangle));
            }

            ValidateDrawingContext();
            DrawFill(rectangle.GetVertexes(), brush, pen);
        }
Esempio n. 5
0
        /// <summary>
        /// 设定矩形数据核心;
        /// </summary>
        /// <param name="rectangle2D"></param>
        private void SetRetangle2DCore(Rectangle2D2 rectangle2D)
        {
            if (rectangle2D == null)
            {
                throw new ArgumentNullException(nameof(rectangle2D));
            }

            _rectangle2D = rectangle2D;
            RaiseVisualChanged();
        }
Esempio n. 6
0
        protected override void OnMouseDown(MouseDownEventArgs e)
        {
            if (e == null)
            {
                throw new ArgumentNullException(nameof(e));
            }

            if (e.Position == null)
            {
                throw new ArgumentException($"The {e.Position} of {nameof(MouseDownEventArgs)} can't be null.");
            }


            e.Handled = true;

            if (CanvasContext.ActiveLayer == null)
            {
                throw new InvalidOperationException($"The {CanvasContext.ActiveLayer} of {nameof(ICanvasContextEx )} can't be null.");
            }

            var thisPosition = e.Position;

            if (thisPosition == null)
            {
                return;
            }

            //若上次按下位置为空,则记录新的点;
            if (_lastMouseDownPosition == null)
            {
                _lastMouseDownPosition = thisPosition;
            }
            //否则将创建一个新的矩形;
            else
            {
                //若对角线两端的横坐标或纵坐标相等,将不能构成一个矩形;
                if (_lastMouseDownPosition.X == thisPosition.X || _lastMouseDownPosition.Y == thisPosition.Y)
                {
                    return;
                }

                //根据四个顶点创建矩形;
                var middleLineY = (thisPosition.Y + _lastMouseDownPosition.Y) / 2;
                var rect2D      = new Rectangle2D2(
                    new Line2D(
                        new Vector2D(_lastMouseDownPosition.X, middleLineY),
                        new Vector2D(thisPosition.X, middleLineY)
                        ),
                    Math.Abs(thisPosition.Y - _lastMouseDownPosition.Y)
                    );
                var rect = new Rectangle(rect2D);
                AddDrawObjectToUndoStack(rect);
                _lastMouseDownPosition = null;
            }
        }
Esempio n. 7
0
        /// <summary>
        /// 得到以某视图坐标为中心的视图矩形;
        /// </summary>
        /// <param name="nativeCenterRectPoint">以视图为准的中心坐标</param>
        /// <param name="width">宽度</param>
        /// <param name="height">高度</param>
        /// <returns></returns>
        public static Rectangle2D2 GetNativeSuroundingScreenRect(Vector2D nativeCenterRectPoint, double width, double height)
        {
            if (nativeCenterRectPoint == null)
            {
                throw new ArgumentNullException(nameof(nativeCenterRectPoint));
            }

            var surroundingRect = Rectangle2D2.CreateEmpty();

            GetNativeSuroundingScreenRect(nativeCenterRectPoint, width, height, surroundingRect);
            return(surroundingRect);
        }
Esempio n. 8
0
        /// <summary>
        /// 检查某个坐标是否处于某个矩形内部;
        /// </summary>
        /// <param name="rect"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public static bool Contains(this Rectangle2D2 rect, Vector2D point)
        {
            if (rect == null)
            {
                throw new ArgumentNullException(nameof(rect));
            }

            if (point == null)
            {
                throw new ArgumentNullException(nameof(point));
            }

            return(point.IsInRegion(rect.GetLines().ToList()));
        }
Esempio n. 9
0
        /// <summary>
        /// 以视图坐标为标准,绘制矩形;
        /// </summary>
        /// <param name="rectangle">以视图坐标为准的矩形</param>
        /// <param name="brush">填充色</param>
        /// <param name="pen">笔</param>
        public void NativeDrawRectangle(Rectangle2D2 rectangle, Brush brush, Pen pen)
        {
            if (rectangle == null)
            {
                throw new ArgumentNullException(nameof(rectangle));
            }

            ValidateDrawingContext();

            var vertexes = rectangle.GetVertexes();

            NativeDrawFill(
                vertexes.Select(p => Vector2DAdapter.ConvertToSystemPoint(p)),
                BrushAdapter.ConvertToSystemBrush(brush),
                PenAdapter.ConverterToSystemPen(pen)
                );
        }
Esempio n. 10
0
        public ISnapShape MatchSnapShape(DrawObject[] drawObjects, Vector2D position, ICanvasContext canvasContext)
        {
            if (drawObjects == null)
            {
                return(null);
            }

#if DEBUG
            //position = new Vector2D(0, 0);
#endif

            var screenPosition = canvasContext.CanvasProxy.ToScreen(position);
            var rect           = Rectangle2D2.CreateEmpty();

            //双游标两两遍历;
            for (int i = 0; i < drawObjects.Length - 1; i++)
            {
                for (int j = i + 1; j < drawObjects.Length; j++)
                {
                    var intersectPositions = DrawObjectIntersectRule.GetIntersectPositions(drawObjects[i], drawObjects[j]);
                    if (intersectPositions == null)
                    {
                        continue;
                    }

                    foreach (var intersectPosition in intersectPositions)
                    {
                        NativeGeometryExtensions.GetNativeSuroundingScreenRect(
                            canvasContext.CanvasProxy.ToScreen(intersectPosition),
                            TolerantedScreenLength,
                            TolerantedScreenLength,
                            rect
                            );


                        if (rect.Contains(screenPosition))
                        {
                            return(new IntersectSnapPoint(intersectPosition));
                        }
                    }
                }
            }

            return(null);
        }
Esempio n. 11
0
        /// <summary>
        /// 判断某个矩形与某个线段的包含或相交(当<paramref name="anyPoint"/>为真时)关系;
        /// </summary>
        /// <param name="line2D"></param>
        /// <param name="rect"></param>
        /// <param name="anyPoint"></param>
        /// <returns></returns>
        public static bool LineInRectangle(Line2D line2D, Rectangle2D2 rect, bool anyPoint)
        {
            if (line2D == null)
            {
                return(false);
            }

            //若在完全在矩形内部,则返回为真;
            if (rect.Contains(line2D.Start) &&
                rect.Contains(line2D.End))
            {
                return(true);
            }
            //若任意可选为真,则矩形任意一条边与之存在相交即可;
            else if (anyPoint)
            {
                return(rect.GetLines()?.Any(p => p.Intersect(line2D) != null) ?? false);
            }
            return(false);
        }
Esempio n. 12
0
        public override bool ObjectInRectangle(Rectangle2D2 rect, ICanvasScreenConvertable canvasProxy, bool anyPoint)
        {
            if (rect == null)
            {
                throw new ArgumentNullException(nameof(rect));
            }

            if (Rectangle2D == null)
            {
                return(false);
            }

            //根据四个顶点的位置判断与指定矩形的包含关系;
            if (anyPoint)
            {
                return(Rectangle2D.GetVertexes()?.Any(p => rect.Contains(p)) ?? false);
            }
            else
            {
                return(Rectangle2D.GetVertexes()?.All(p => rect.Contains(p)) ?? false);
            }
        }
Esempio n. 13
0
        public override void Draw(ICanvas canvas, ICanvasScreenConvertable canvasProxy)
        {
            if (canvas == null)
            {
                throw new ArgumentNullException(nameof(canvas));
            }

            base.Draw(canvas, canvasProxy);

            if (_lastMouseDownPosition == null || _currentMousePosition == null)
            {
                return;
            }

            //若对角线的两端纵坐标或横坐标相等,则不进行绘制;
            if (_currentMousePosition.X == _lastMouseDownPosition.X || _lastMouseDownPosition.Y == _currentMousePosition.Y)
            {
                return;
            }

            //绘制编辑的矩形的预览状态;
            var middleLineY = (_currentMousePosition.Y + _lastMouseDownPosition.Y) / 2;
            var rect2D      = new Rectangle2D2(
                new Line2D(
                    new Vector2D(_lastMouseDownPosition.X, middleLineY),
                    new Vector2D(_currentMousePosition.X, middleLineY)
                    ),
                Math.Abs(_currentMousePosition.Y - _lastMouseDownPosition.Y)
                );

            canvas.DrawRectangle(
                rect2D,
                NormalRectColorBrush,
                NormalRectPen
                );
        }
Esempio n. 14
0
        /// <summary>
        /// 根据裁剪对象<paramref name="trimingDrawObjects"/>和裁剪区域<paramref name="trimArea"/>,
        /// 对被裁剪对象<paramref name="toBeTrimedDrawObject"/>进行裁剪,
        /// 返回裁剪后的对象;
        /// </summary>
        /// <param name="canvasContext"></param>
        /// <param name="trimArea"></param>
        private DrawObject[] GetTrimedOrExtendedDrawObjects(
            DrawObject toBeTrimedDrawObject,
            IEnumerable <DrawObject> trimingDrawObjects,
            Rectangle2D2 trimArea
            )
        {
            if (toBeTrimedDrawObject == null)
            {
                throw new ArgumentNullException(nameof(toBeTrimedDrawObject));
            }

            if (trimingDrawObjects == null)
            {
                throw new ArgumentNullException(nameof(trimingDrawObjects));
            }

            ///得到所有被裁剪绘制对象与裁剪对象的交点;
            var thisIntersectPositions = trimingDrawObjects.SelectMany(
                p => DrawObjectIntersectRules.SelectMany(
                    q => q.GetIntersectPositions(toBeTrimedDrawObject, p, IsExtendMode) ?? Enumerable.Empty <Vector2D>()
                    )
                ).ToArray();

            if (thisIntersectPositions.Length == 0)
            {
                return(null);
            }

            DrawObject[] thisCreatedDrawObjects = null;

            //若非延伸模式,则进行裁剪计算;
            if (!IsExtendMode)
            {
                //找到对应的裁剪工具;
                var trimTool = DrawObjectTrimTools.FirstOrDefault(p => p.CheckIsValidDrawObject(toBeTrimedDrawObject));

                if (trimTool == null)
                {
                    return(null);
                }

                //进行裁剪;
                thisCreatedDrawObjects = trimTool.TrimDrawObject(
                    new DrawObjectTrimingInfo {
                    TrimedDrawObject   = toBeTrimedDrawObject,
                    TrimingDrawObjects = trimingDrawObjects.ToArray(),
                    IntersectPositions = thisIntersectPositions,
                    TrimArea           = trimArea
                }
                    );
            }
            //否则延伸计算;
            else
            {
                var extendTool = DrawObjectExtendTools.FirstOrDefault(p => p.CheckIsValidDrawObject(toBeTrimedDrawObject));

                if (extendTool == null)
                {
                    return(null);
                }

                //进行延伸;
                var createdDrawObject = extendTool.ExtendDrawObject(
                    new DrawObjectExtendInfo {
                    ExtendedDrawObject   = toBeTrimedDrawObject,
                    ExtendingDrawObjects = trimingDrawObjects.ToArray(),
                    ExtendArea           = trimArea,
                    IntersectPositions   = thisIntersectPositions
                }
                    );

                if (createdDrawObject == null)
                {
                    return(null);
                }

                thisCreatedDrawObjects = new DrawObject[] { createdDrawObject };
            }

            //返回裁剪后的绘制对象;
            return(thisCreatedDrawObjects);
        }
Esempio n. 15
0
        /// <summary>
        /// 将线段限制到可见范围内;
        /// </summary>
        /// <param name="line">原坐标</param>
        /// <returns>返回可见的线段</returns>
        private static Line2D GetLimitedLine2D(Line2D line, Rectangle2D2 rect)
        {
            var visibleLine = new Line2D(line.Start, line.End);

            return(visibleLine);
        }
Esempio n. 16
0
        public static Line2D GetExtendLineWithIntersectPositions(Line2D line2D, Line2D[] extendLines, Vector2D[] intersectPositions, Rectangle2D2 rectIntersect)
        {
            if (extendLines.Length == 0)
            {
                return(null);
            }
            if (rectIntersect == null)
            {
                return(null);
            }
            if (intersectPositions.Length == 0)
            {
                return(null);
            }
            if (rectIntersect.Contains(line2D.Start) && rectIntersect.Contains(line2D.End) && intersectPositions.Length == 2)
            {
                var p1 = intersectPositions[0];
                var p2 = intersectPositions[1];
                if (line2D.Start.IsInLine(Line2D.Create(p1, line2D.End)))
                {
                    return(Line2D.Create(p1, p2));
                }
                return(Line2D.Create(p2, p1));
            }

            if (rectIntersect.Contains(line2D.Start))
            {
                return(Line2D.Create(intersectPositions.First(), line2D.End));
            }
            if (rectIntersect.Contains(line2D.End))
            {
                return(Line2D.Create(line2D.Start, intersectPositions.First()));
            }
            return(null);
        }
 public DragSelectMouseMoveEventArgs(Rectangle2D2 rectangle2D, Vector2D position) : base(position)
 {
 }
Esempio n. 18
0
 /// <summary>
 /// 判定绘制对象是否在某个矩形区域内;
 /// </summary>
 /// <param name="rect">区域(工程数学坐标为准)</param>
 /// <param name="anyPoint">是否模糊匹配,即判定相交是否满足条件</param>
 /// <param name="canvasProxy">视图单位转化器,可用于内部进行误差判断</param>
 /// <returns></returns>
 public abstract bool ObjectInRectangle(Rectangle2D2 rect, ICanvasScreenConvertable canvasProxy, bool anyPoint);
Esempio n. 19
0
        public static Line2D GetExtendMemberWithIntersectPositions(Line2D line2D, Line2D[] extendLines, Vector2D[] intersectPositions, Rectangle2D2 rectIntersect, double width, double gap)
        {
            if (extendLines.Length == 0)
            {
                return(null);
            }
            if (rectIntersect == null)
            {
                return(null);
            }
            if (intersectPositions.Length == 0)
            {
                return(null);
            }
            if (rectIntersect.Contains(line2D.Start) && rectIntersect.Contains(line2D.End) && intersectPositions.Length == 2)
            {
                var p1     = intersectPositions[0];
                var p2     = intersectPositions[1];
                var line1  = extendLines.First(x => p1.IsInLine(x));
                var angle1 = line1.Direction.AngleWith(line2D.Direction);
                var newP1  = GetExtendPoint(p1, -line2D.Direction, angle1, width, gap);
                var line2  = extendLines.First(x => p2.IsInLine(x));
                var angle2 = line2.Direction.AngleWith(line2D.Direction);
                var newP2  = GetExtendPoint(p2, line2D.Direction, angle2, width, gap);
                if (line2D.Start.IsInLine(Line2D.Create(p1, line2D.End)))
                {
                    return(Line2D.Create(newP1, newP2));
                }

                return(Line2D.Create(newP2, newP1));
            }

            if (rectIntersect.Contains(line2D.Start) && line2D.Start.IsInLine(Line2D.Create(intersectPositions.First(), line2D.End)))
            {
                var angle       = line2D.Direction.AngleWith(extendLines[0].Direction);
                var newEndPoint = GetExtendPoint(intersectPositions.First(), -line2D.Direction, angle, width, gap);
                return(Line2D.Create(newEndPoint, line2D.End));
            }

            if (rectIntersect.Contains(line2D.End) && line2D.End.IsInLine(Line2D.Create(intersectPositions.First(), line2D.Start)))
            {
                var angle       = line2D.Direction.AngleWith(extendLines[0].Direction);
                var newEndPoint = GetExtendPoint(intersectPositions.First(), line2D.Direction, angle, width, gap);
                return(Line2D.Create(line2D.Start, newEndPoint));
            }
            return(null);
        }
Esempio n. 20
0
 public override bool ObjectInRectangle(Rectangle2D2 rect, ICanvasScreenConvertable canvasProxy, bool anyPoint)
 {
     return(LineHitUtils.LineInRectangle(MeasureLineP, rect, anyPoint) ||
            LineHitUtils.LineInRectangle(MeasureLineV0, rect, anyPoint) ||
            LineHitUtils.LineInRectangle(MeasureLineV1, rect, anyPoint));
 }
Esempio n. 21
0
        /// <summary>
        /// 得到以某视图坐标为中心的视图矩形;
        /// </summary>
        /// <param name="nativeCenterRectPoint">以视图为准的中心坐标</param>
        /// <param name="width">宽度</param>
        /// <param name="height">高度</param>
        /// <param name="rectangle2D2">用于写入的矩形实例</param>
        /// <returns></returns>
        public static void GetNativeSuroundingScreenRect(Vector2D nativeCenterRectPoint, double width, double height, Rectangle2D2 rectangle2D2)
        {
            if (nativeCenterRectPoint == null)
            {
                throw new ArgumentNullException(nameof(nativeCenterRectPoint));
            }

            if (rectangle2D2 == null)
            {
                throw new ArgumentNullException(nameof(rectangle2D2));
            }

            rectangle2D2.MiddleLine2D = new Line2D(
                new Vector2D(nativeCenterRectPoint.X - width / 2, nativeCenterRectPoint.Y),
                new Vector2D(nativeCenterRectPoint.X + width / 2, nativeCenterRectPoint.Y)
                );
            rectangle2D2.Width = height;
        }
Esempio n. 22
0
 /// <summary>
 /// 判定绘制对象是否在某个矩形区域内;
 /// </summary>
 /// <param name="rect">区域(工程数学坐标为准)</param>
 /// <param name="anyPoint">是否模糊匹配,即判定相交是否满足条件</param>
 /// <param name="canvasProxy">视图单位转化器,可用于内部进行误差判断</param>
 /// <returns></returns>
 public virtual bool ObjectInRectangle(Rectangle2D2 rect, ICanvasScreenConvertable canvasProxy, bool anyPoint) => false;
Esempio n. 23
0
 public DragSelectEventArgs(Vector2D position, Rectangle2D2 rectangle2D, DrawObject[] hitedDrawObjects)
 {
     Position         = position ?? throw new ArgumentNullException(nameof(position));
     Rectangle2D      = rectangle2D ?? throw new ArgumentNullException(nameof(rectangle2D));
     HitedDrawObjects = hitedDrawObjects ?? throw new ArgumentNullException(nameof(hitedDrawObjects));
 }
Esempio n. 24
0
 public override bool ObjectInRectangle(Rectangle2D2 rect, ICanvasScreenConvertable canvasProxy, bool anyPoint)
 {
     return(false);
 }