Beispiel #1
0
        private void MouseDownSetBridge(MouseEventArgs e)
        {
            UnitPoint mousePoint = this.ToUnit(this.mouseDownPoint);

            if (this.bridgeStart.IsEmpty)
            {
                this.bridgeStart = mousePoint;
            }
            else
            {
                this.bridgeEnd = mousePoint;
                BridgingModel param = this.bridgeFunc?.Invoke();
                if (param != null)
                {
                    //1.获取图形区域与桥接直线交叉的图形
                    var  oldObjects = this.Model.DrawingLayer.Objects.FindAll(f => HitUtil.LineIntersectWithRect(this.bridgeStart, this.bridgeEnd, f.GetBoundingRectangle(BoundingRectangleType.All)));
                    bool isChanged  = false;
                    //2.计算直线与图形的交点
                    var newObjects = BridgeHelper.GetBridgeObjects(oldObjects, this.bridgeStart, this.bridgeEnd, param, out isChanged);
                    if (isChanged)
                    {
                        this.Model.DoBridge(newObjects, oldObjects, true);
                    }
                }
                this.CommandEscape();
            }
        }
Beispiel #2
0
 public FrmBridging(BridgingModel bridging) : this()
 {
     this.Model = CopyUtil.DeepCopy(bridging);
     if (this.Model.MaxDistance == 0)
     {
         this.Model.MaxDistance = 100;
     }
     if (this.Model.Width == 0)
     {
         this.Model.Width = 10;
     }
     if (!this.mvvmContext1.IsDesignMode)
     {
         if (this.Model == null)
         {
             this.Model = new BridgingModel();
         }
         this.mvvmContext1.SetViewModel(typeof(BridgingModel), this.Model);
         this.InitializeBindings();
     }
 }
Beispiel #3
0
        private static List <BridgePoints> GetBridgeByMultiSegLine(MultiSegmentLineBase multiSegLine, UnitPoint p1, UnitPoint p2, BridgingModel param)
        {
            List <BridgePoints> retPoints = new List <BridgePoints>();
            var    line      = DrawingOperationHelper.GetLineEquation(p1, p2);
            double width     = param.Width / 2;
            var    oriPoints = multiSegLine.Points;

            for (int index = 0; index < oriPoints.Count; index++)
            {
                int            next   = (index + 1 == oriPoints.Count) ? 0 : index + 1;
                UnitPointBulge point1 = oriPoints[index];
                UnitPointBulge point2 = oriPoints[next];
                if (!multiSegLine.IsCloseFigure && index == oriPoints.Count - 1)
                {
                    break;
                }
                if (!double.IsNaN(point1.Bulge))
                {
                    //圆弧
                    ArcModelMini arcMini = DrawingOperationHelper.GetArcParametersFromBulge(point1.Point, point2.Point, (float)point1.Bulge);
                    arcMini.StartAngle = (float)HitUtil.RadiansToDegrees(arcMini.StartAngle);
                    arcMini.EndAngle   = (float)HitUtil.RadiansToDegrees(arcMini.EndAngle);
                    List <UnitPoint> points = DrawingOperationHelper.GetIntersectPointByLineAndCircle(line.Item1, line.Item2, line.Item3, arcMini.Center, arcMini.Radius);
                    var hasPoints           = points?.Where(p => !p.IsEmpty && HitUtil.IsPointOnArc(p, 0.000001f, arcMini) && HitUtil.IsPointInLine(p1, p2, p, 0.000001f)).ToList();
                    if (hasPoints != null && hasPoints.Count > 0)
                    {
                        arcMini.StartAngle = (float)HitUtil.DegreesToRadians(arcMini.StartAngle);
                        arcMini.EndAngle   = (float)HitUtil.DegreesToRadians(arcMini.EndAngle);
                        //根据宽度求点
                        double arcLength = DrawingOperationHelper.GetArcLength(arcMini.Radius, arcMini.SweepAngle);
                        hasPoints?.ForEach(p =>
                        {
                            double percent = DrawingOperationHelper.GetPercentInArcByPoint(arcMini, p);
                            //第一个位置点
                            double length1       = arcLength * (1 - percent) + width;
                            UnitPointBulge retP1 = GetEndPointByLength(oriPoints, index, length1, false);

                            //第二个位置点
                            double length2       = arcLength * percent + width;
                            UnitPointBulge retP2 = GetEndPointByLength(oriPoints, index, length2, true);

                            var bridge = new BridgePoints(multiSegLine, retP1, retP2, HitUtil.Distance(p1, p));
                            retPoints.Add(bridge);
                        });
                    }
                }
                else
                {
                    //直线
                    var       lineABC = DrawingOperationHelper.GetLineEquation(point1.Point, point2.Point);
                    UnitPoint point   = DrawingOperationHelper.GetIntersectionPointBy2Line(line.Item1, line.Item2, line.Item3, lineABC.Item1, lineABC.Item2, lineABC.Item3);
                    if (!point.IsEmpty && HitUtil.IsPointInLine(point1.Point, point2.Point, point, 0.000001f) && HitUtil.IsPointInLine(p1, p2, point, 0.000001f))
                    {
                        //第一个位置点
                        double         lenght1 = HitUtil.Distance(point2.Point, point) + width;
                        UnitPointBulge retP1   = GetEndPointByLength(oriPoints, index, lenght1, false);


                        //第二个位置点
                        double         lenght2 = HitUtil.Distance(point1.Point, point) + width;
                        UnitPointBulge retP2   = GetEndPointByLength(oriPoints, index, lenght2, true);

                        var bridge = new BridgePoints(multiSegLine, retP1, retP2, HitUtil.Distance(p1, point));
                        retPoints.Add(bridge);
                    }
                }
            }
            return(retPoints);
        }
Beispiel #4
0
        private static List <BridgePoints> GetBridgeByArc(ArcBase arc, UnitPoint p1, UnitPoint p2, BridgingModel param)
        {
            List <BridgePoints> retPoints = new List <BridgePoints>();
            var          line             = DrawingOperationHelper.GetLineEquation(p1, p2);
            double       width            = param.Width / 2;
            ArcModelMini arcMini          = new DrawModel.ArcModelMini()
            {
                Center     = arc.Center,
                Radius     = arc.Radius,
                StartAngle = arc.StartAngle,
                EndAngle   = arc.EndAngle,
                SweepAngle = arc.AngleSweep,
                Clockwise  = arc.IsClockwise
            };

            List <UnitPoint> points = DrawingOperationHelper.GetIntersectPointByLineAndCircle(line.Item1, line.Item2, line.Item3, arc.Center, arc.Radius);
            var hasPoints           = points?.Where(p => !p.IsEmpty && (HitUtil.IsPointOnArc(p, 0.000001f, arcMini) && HitUtil.IsPointInLine(p1, p2, p, 0.000001f))).ToList();

            if (hasPoints != null && hasPoints.Count > 0)
            {
                //根据宽度求点
                double angle = width / arc.Radius * (arc.IsClockwise ? 1 : -1);
                hasPoints?.ForEach(p =>
                {
                    double lineAngle    = HitUtil.LineAngleR(arcMini.Center, p, 0);
                    double angle1       = lineAngle + angle;
                    double angle2       = lineAngle - angle;
                    UnitPoint retPoint1 = UnitPoint.Empty;
                    UnitPoint retPoint2 = UnitPoint.Empty;
                    if (HitUtil.IsPointInArc(HitUtil.RadiansToDegrees(angle1), arcMini.StartAngle, arcMini.EndAngle, arcMini.Clockwise))
                    {
                        //第一个位置点
                        retPoint1 = HitUtil.PointOnCircle(arcMini.Center, arcMini.Radius, angle1);
                    }
                    if (HitUtil.IsPointInArc(HitUtil.RadiansToDegrees(angle2), arcMini.StartAngle, arcMini.EndAngle, arcMini.Clockwise))
                    {
                        //第二个位置点
                        retPoint2 = HitUtil.PointOnCircle(arcMini.Center, arcMini.Radius, angle2);
                    }
                    BridgePoints bridges = new BridgePoints(arc,
                                                            new UnitPointBulge(retPoint1),
                                                            new UnitPointBulge(retPoint2),
                                                            HitUtil.Distance(p1, p));
                    retPoints.Add(bridges);
                });
            }
            return(retPoints);
        }
Beispiel #5
0
        private static List <BridgePoints> GetBridgeByCircle(Circle circle, UnitPoint p1, UnitPoint p2, BridgingModel param)
        {
            List <BridgePoints> retPoints = new List <BridgePoints>();
            var              line         = DrawingOperationHelper.GetLineEquation(p1, p2);
            double           width        = param.Width / 2;
            List <UnitPoint> points       = DrawingOperationHelper.GetIntersectPointByLineAndCircle(line.Item1, line.Item2, line.Item3, circle.Center, circle.Radius);
            var              hasPoints    = points?.Where(p => !p.IsEmpty && HitUtil.IsPointInLine(p1, p2, p, 0.000001f)).ToList();

            if (hasPoints != null && hasPoints.Count > 0)
            {
                //根据宽度求点
                double angle = width / circle.Radius * (circle.IsClockwise ? 1 : -1);
                List <UnitPointBulge> temps = new List <UnitPointBulge>();
                hasPoints?.ForEach(p =>
                {
                    double lineAngle = HitUtil.LineAngleR(circle.Center, p, 0);
                    double angle1    = lineAngle + angle;
                    double angle2    = lineAngle - angle;
                    //第一个位置点
                    UnitPoint retPoint1 = HitUtil.PointOnCircle(circle.Center, circle.Radius, angle1);
                    //第二个位置点
                    UnitPoint retPoint2 = HitUtil.PointOnCircle(circle.Center, circle.Radius, angle2);

                    BridgePoints bridges = new BridgePoints(circle,
                                                            new UnitPointBulge(retPoint1),
                                                            new UnitPointBulge(retPoint2),
                                                            HitUtil.Distance(p1, p));
                    retPoints.Add(bridges);
                });
            }
            return(retPoints);
        }
Beispiel #6
0
        public static List <IDrawObject> GetBridgeObjects(List <IDrawObject> drawObjects, UnitPoint p1, UnitPoint p2, BridgingModel param, out bool isChanged)
        {
            isChanged = false;//桥接是否改变了图形
            List <BridgePoints> bridgePoints = new List <BridgePoints>();

            #region 计算桥接点在图形中的点的坐标
            drawObjects?.ForEach(drawObject =>
            {
                if ((drawObject.FigureType == FigureTypes.Circle))
                {
                    Circle circle = drawObject as Circle;
                    var bridges   = BridgeHelper.GetBridgeByCircle(circle, p1, p2, param);
                    bridgePoints.AddRange(bridges);
                }
                else if (drawObject.FigureType == FigureTypes.Arc)
                {
                    ArcBase arc = drawObject as ArcBase;
                    var bridges = BridgeHelper.GetBridgeByArc(arc, p1, p2, param);
                    bridgePoints.AddRange(bridges);
                }
                else if (drawObject.FigureType == FigureTypes.LwPolyline)
                {
                    MultiSegmentLineBase multiSegLine = drawObject as MultiSegmentLineBase;
                    var bridges = BridgeHelper.GetBridgeByMultiSegLine(multiSegLine, p1, p2, param);
                    bridgePoints.AddRange(bridges);
                }
            });
            #endregion

            #region 根据桥接点坐标,按直线的起点距离排序,如果奇数个将移除最后一个,保证偶数个可以连接
            bridgePoints.Sort((x, y) => { if (x.Distance > y.Distance)
                                          {
                                              return(1);
                                          }
                                          return(-1); });
            if (bridgePoints.Count % 2 == 1)
            {
                bridgePoints.RemoveAt(bridgePoints.Count - 1);
            }
            #endregion

            #region 移除间距大于最大条件的点
            List <BridgePoints> removes = new List <BridgePoints>();
            for (int i = 0; i < bridgePoints.Count - 1; i += 2)
            {
                var bridge1 = bridgePoints[i];
                var bridge2 = bridgePoints[i + 1];
                if (Math.Abs(bridge1.Distance - bridge2.Distance) > param.MaxDistance)
                {
                    removes.Add(bridge1);
                    removes.Add(bridge2);
                }
            }
            removes.ForEach(e => bridgePoints.Remove(e));
            #endregion

            if (bridgePoints.Count > 0)
            {
                List <IDrawObject> temps    = new List <IDrawObject>(); //计算后的图形
                List <IDrawObject> oldDraws = new List <IDrawObject>(); //不用计算的原图

                #region 根据桥接点的位置把原图形拆为多段线
                foreach (IDrawObject drawObject in drawObjects)
                {
                    var points = bridgePoints.FindAll(b => b.Owner == drawObject);
                    if (points.Count > 0)
                    {
                        List <IDrawObject> draws = null;
                        if (drawObject.FigureType == FigureTypes.Circle)
                        {
                            draws = BridgeHelper.ConvertToMultiSegLine(drawObject as Circle, points);
                        }
                        else if (drawObject.FigureType == FigureTypes.Arc)
                        {
                            draws = BridgeHelper.ConvertToMultiSegLine(drawObject as ArcBase, points);
                        }
                        else if (drawObject.FigureType == FigureTypes.LwPolyline)
                        {
                            draws = BridgeHelper.ConvertToMultiSegLine(drawObject as MultiSegmentLineBase, points);
                        }
                        if (draws != null)
                        {
                            draws.RemoveAll(p => (p as MultiSegmentLineBase).Points.Count < 2);
                            temps.AddRange(draws);
                        }
                    }
                    else
                    {
                        oldDraws.Add(drawObject);
                    }
                }
                #endregion

                #region 连接最新的桥接图形
                for (int i = 0; i < bridgePoints.Count - 1; i += 2)
                {
                    var                  bridge1    = bridgePoints[i];
                    var                  bridge2    = bridgePoints[i + 1];
                    bool                 clockwise1 = HitUtil.IsClockwiseByCross(p1, p2, bridge1.Point1.Point);
                    bool                 clockwise2 = HitUtil.IsClockwiseByCross(p1, p2, bridge2.Point1.Point);
                    UnitPointBulge       point11    = !clockwise1 ? bridge1.Point1 : bridge1.Point2;
                    UnitPointBulge       point12    = clockwise1 ? bridge1.Point1 : bridge1.Point2;
                    UnitPointBulge       point21    = !clockwise2 ? bridge2.Point1 : bridge2.Point2;
                    UnitPointBulge       point22    = clockwise2 ? bridge2.Point1 : bridge2.Point2;
                    MultiSegmentLineBase draw11     = temps.Find(d => (d as MultiSegmentLineBase).Points.Contains(point11)) as MultiSegmentLineBase;
                    MultiSegmentLineBase draw12     = temps.Find(d => (d as MultiSegmentLineBase).Points.Contains(point12)) as MultiSegmentLineBase;
                    MultiSegmentLineBase draw21     = temps.Find(d => (d as MultiSegmentLineBase).Points.Contains(point21)) as MultiSegmentLineBase;
                    MultiSegmentLineBase draw22     = temps.Find(d => (d as MultiSegmentLineBase).Points.Contains(point22)) as MultiSegmentLineBase;
                    if (draw11 == null)
                    {
                        draw11 = new MultiSegmentLineBase()
                        {
                            LayerId = (bridge1.Owner as DrawObjectBase).LayerId, GroupParam = CopyUtil.DeepCopy(bridge1.Owner.GroupParam), Points = new List <UnitPointBulge>()
                        };
                    }
                    if (draw12 == null)
                    {
                        draw12 = new MultiSegmentLineBase()
                        {
                            LayerId = (bridge1.Owner as DrawObjectBase).LayerId, GroupParam = CopyUtil.DeepCopy(bridge1.Owner.GroupParam), Points = new List <UnitPointBulge>()
                        };
                    }
                    if (draw21 == null)
                    {
                        draw21 = new MultiSegmentLineBase()
                        {
                            LayerId = (bridge2.Owner as DrawObjectBase).LayerId, GroupParam = CopyUtil.DeepCopy(bridge2.Owner.GroupParam), Points = new List <UnitPointBulge>()
                        };
                    }
                    if (draw22 == null)
                    {
                        draw22 = new MultiSegmentLineBase()
                        {
                            LayerId = (bridge2.Owner as DrawObjectBase).LayerId, GroupParam = CopyUtil.DeepCopy(bridge2.Owner.GroupParam), Points = new List <UnitPointBulge>()
                        };
                    }
                    #region 组合多段线
                    if (draw11 == draw12 && draw21 == draw22)
                    {
                        if (draw11.Points.Count > 0 && draw11.Points[0] == point11)
                        {
                            draw11.ReverseDirection();
                        }
                        if (draw21.Points.Count > 0 && draw21.Points[0] != point21)
                        {
                            draw11.ReverseDirection();
                        }
                        if (draw11.Points.Count > 0)
                        {
                            draw11.Points[draw11.Points.Count - 1].Bulge = double.NaN;
                        }
                        if (draw21.Points.Count > 0)
                        {
                            draw21.Points[draw21.Points.Count - 1].Bulge = double.NaN;
                        }
                        draw11.Points.AddRange(draw21.Points);
                        draw11.IsCloseFigure = true;
                        temps.Remove(draw21);
                    }
                    else if (draw11 == draw12 && draw21 != draw22)
                    {
                        if (draw21.Points.Count > 0 && draw21.Points[0] == point21)
                        {
                            draw21.ReverseDirection();
                        }
                        if (draw22.Points.Count > 0 && draw22.Points[0] != point22)
                        {
                            draw22.ReverseDirection();
                        }
                        if (draw11.Points.Count > 0 && draw11.Points[0] != point11)
                        {
                            draw11.ReverseDirection();
                        }
                        if (draw21.Points.Count > 0)
                        {
                            draw21.Points[draw21.Points.Count - 1].Bulge = double.NaN;
                        }
                        if (draw11.Points.Count > 0)
                        {
                            draw11.Points[draw11.Points.Count - 1].Bulge = double.NaN;
                        }
                        draw21.Points.AddRange(draw11.Points);
                        draw21.Points.AddRange(draw22.Points);
                        temps.Remove(draw11);
                        temps.Remove(draw22);
                    }
                    else if (draw11 != draw12 && draw21 == draw22)
                    {
                        if (draw11.Points.Count > 0 && draw11.Points[0] == point11)
                        {
                            draw11.ReverseDirection();
                        }
                        if (draw21.Points.Count > 0 && draw21.Points[0] != point21)
                        {
                            draw21.ReverseDirection();
                        }
                        if (draw12.Points.Count > 0 && draw12.Points[0] != point12)
                        {
                            draw12.ReverseDirection();
                        }
                        if (draw11.Points.Count > 0)
                        {
                            draw11.Points[draw11.Points.Count - 1].Bulge = double.NaN;
                        }
                        if (draw21.Points.Count > 0)
                        {
                            draw21.Points[draw21.Points.Count - 1].Bulge = double.NaN;
                        }
                        draw11.Points.AddRange(draw21.Points);
                        draw11.Points.AddRange(draw12.Points);
                        temps.Remove(draw21);
                        temps.Remove(draw12);
                    }
                    else if (draw11 == draw21 && draw12 == draw22)
                    {
                        if (draw11.Points.Count > 0 && draw11.Points[0] != point11)
                        {
                            draw11.ReverseDirection();
                        }
                        if (draw12.Points.Count > 0 && draw12.Points[0] != point12)
                        {
                            draw12.ReverseDirection();
                        }
                        if (draw11.Points.Count > 0)
                        {
                            draw11.Points[draw11.Points.Count - 1].Bulge = double.NaN;
                        }
                        if (draw12.Points.Count > 0)
                        {
                            draw12.Points[draw12.Points.Count - 1].Bulge = double.NaN;
                        }
                        draw11.IsCloseFigure = true;
                        draw12.IsCloseFigure = true;
                    }
                    else if (draw11 == draw21 && draw12 != draw22)
                    {
                        if (draw11.Points.Count > 0 && draw11.Points[0] != point11)
                        {
                            draw11.ReverseDirection();
                        }
                        if (draw12.Points.Count > 0 && draw12.Points[0] == point12)
                        {
                            draw12.ReverseDirection();
                        }
                        if (draw22.Points.Count > 0 && draw22.Points[0] != point22)
                        {
                            draw22.ReverseDirection();
                        }
                        if (draw11.Points.Count > 0)
                        {
                            draw11.Points[draw11.Points.Count - 1].Bulge = double.NaN;
                        }
                        if (draw12.Points.Count > 0)
                        {
                            draw12.Points[draw12.Points.Count - 1].Bulge = double.NaN;
                        }
                        draw11.IsCloseFigure = true;
                        draw12.Points.AddRange(draw22.Points);
                        temps.Remove(draw22);
                    }
                    else if (draw11 != draw21 && draw12 == draw22)
                    {
                        if (draw12.Points.Count > 0 && draw12.Points[0] != point12)
                        {
                            draw12.ReverseDirection();
                        }
                        if (draw11.Points.Count > 0 && draw11.Points[0] == point11)
                        {
                            draw11.ReverseDirection();
                        }
                        if (draw21.Points.Count > 0 && draw21.Points[0] != point21)
                        {
                            draw21.ReverseDirection();
                        }
                        if (draw12.Points.Count > 0)
                        {
                            draw12.Points[draw12.Points.Count - 1].Bulge = double.NaN;
                        }
                        if (draw11.Points.Count > 0)
                        {
                            draw11.Points[draw11.Points.Count - 1].Bulge = double.NaN;
                        }
                        draw12.IsCloseFigure = true;
                        draw11.Points.AddRange(draw21.Points);
                        temps.Remove(draw21);
                    }
                    else
                    {
                        if (draw11.Points.Count > 0 && draw11.Points[0] == point11)
                        {
                            draw11.ReverseDirection();
                        }
                        if (draw21.Points.Count > 0 && draw21.Points[0] != point21)
                        {
                            draw21.ReverseDirection();
                        }
                        if (draw12.Points.Count > 0 && draw12.Points[0] == point12)
                        {
                            draw12.ReverseDirection();
                        }
                        if (draw22.Points.Count > 0 && draw22.Points[0] != point22)
                        {
                            draw22.ReverseDirection();
                        }
                        if (draw11.Points.Count > 0)
                        {
                            draw11.Points[draw11.Points.Count - 1].Bulge = double.NaN;
                        }
                        if (draw12.Points.Count > 0)
                        {
                            draw12.Points[draw12.Points.Count - 1].Bulge = double.NaN;
                        }
                        draw11.Points.AddRange(draw21.Points);
                        draw12.Points.AddRange(draw22.Points);
                        temps.Remove(draw21);
                        temps.Remove(draw22);
                    }
                    #endregion
                }
                #endregion

                isChanged = true;
                temps.ForEach(d => d.Update());
                temps.AddRange(oldDraws);
                return(temps);
            }
            return(drawObjects);
        }