Beispiel #1
0
        public ICrossPoint[] GetCrossPoint(Vex.Point snapPoint, BondAttachment ba)
        {
            List <ICrossPoint> result = new List <ICrossPoint>();

            if (ba.IsHandle())
            {
                if (xStops.ContainsKey(snapPoint.X)) // will not contain point if snaping to original position
                {
                    List <ICrossPoint> cps = xStops[snapPoint.X];
                    ICrossPoint        cp  = cps.Find(item => item.CrossStart == snapPoint.Y);
                    if (cp != null)
                    {
                        result.Add(cp);
                    }
                }
            }
            else
            {
                if (ba.IsVGuide())
                {
                    List <ICrossPoint> cps = xStops[snapPoint.X];
                    if (cps.Count > 0)
                    {
                        result.Add(cps[0]);
                    }
                }
                if (ba.IsHGuide())
                {
                    List <ICrossPoint> cps = yStops[snapPoint.Y];
                    if (cps.Count > 0)
                    {
                        result.Add(cps[0]);
                    }
                }
            }
            return(result.ToArray());
        }
Beispiel #2
0
        public Vex.Point GetSnapPoints(PointF[] pts, ref Vex.Point[] snapPoints, ref BondAttachment[] snapTypes)
        {
            Vex.Point resultOffset = Vex.Point.Zero;

            // get first snap point for each handle point (based on top left)
            Vex.Point[] snapsXP = new Vex.Point[pts.Length];
            Vex.Point[] snapsY  = new Vex.Point[pts.Length];
            for (int i = 0; i < pts.Length; i++)
            {
                snapsXP[i] = Vex.Point.Empty;
                snapsY[i]  = Vex.Point.Empty;
                GetSnapPoint(xStops, pts[i].X, pts[i].Y, ref snapsXP[i].X, ref snapsXP[i].Y);
                GetSnapPoint(yStops, pts[i].Y, pts[i].X, ref snapsY[i].Y, ref snapsY[i].X, false);
            }

            // get closest X and Y
            float bestDist  = float.MaxValue;
            float bestDistX = float.MaxValue;
            float bestDistY = float.MaxValue;

            Vex.Point bestPoint = Vex.Point.Empty;

            Dictionary <int, BondAttachment> bestIndexes = new Dictionary <int, BondAttachment>();

            for (int i = 0; i < snapsXP.Length; i++)
            {
                // find the distance to the snap(s) for the given handle
                Vex.Point      rp   = snapsXP[i];
                float          difX = 0;
                float          difY = 0;
                BondAttachment targ = BondAttachment.None;
                if (!float.IsNaN(rp.X) && !float.IsNaN(rp.Y)) // point
                {
                    targ = BondAttachment.SymbolHandle;
                    difX = rp.X - pts[i].X;
                    difY = rp.Y - pts[i].Y;
                }
                else if (!float.IsNaN(rp.X)) // vertical guide
                {
                    targ = BondAttachment.VGuide;
                    difX = rp.X - pts[i].X;
                }
                rp = snapsY[i];
                if (float.IsNaN(rp.X) && !float.IsNaN(rp.Y)) // horizontal guide
                {
                    targ = (targ == BondAttachment.VGuide) ? BondAttachment.CornerGuide : BondAttachment.HGuide;
                    difY = rp.Y - pts[i].Y;
                }


                // check if close enough to win or tie
                float distX = difX * difX;
                float distY = difY * difY;
                if (targ.IsHandle())
                {
                    float dist = distX + distY;
                    if (dist <= bestDist + 0.001f)
                    {
                        if (dist + 0.001f < bestDist &&
                            (bestPoint.IsEmpty || Math.Abs(difX - bestPoint.X) < 0.001 || Math.Abs(difY - bestPoint.Y) < 0.001))
                        {
                            bestIndexes.Clear();
                            bestDist  = dist;
                            bestPoint = new Vex.Point(difX, difY);
                            bestDistX = distX;
                            bestDistY = distY;
                            bestIndexes.Add(i, targ);
                        }
                        else if (Math.Abs(distX - bestDistX) < 0.001 && Math.Abs(distY - bestDistY) < 0.001)
                        {
                            bestIndexes.Add(i, targ);
                        }
                    }
                }
                else if (targ != BondAttachment.None)  // guides
                {
                    float minXY = Math.Min(distX, distY);

                    if (minXY < bestDist - 0.0001f)
                    {
                        foreach (var item in bestIndexes.Where(kpv => kpv.Value == BondAttachment.SymbolHandle).ToList())
                        {
                            bestIndexes.Remove(item.Key);
                        }
                        bestDist = minXY;
                    }

                    if (targ == BondAttachment.CornerGuide)
                    {
                        if (distX - 0.0001f <= bestDistX || difY - 0.0001f <= bestDistY)
                        {
                            foreach (var item in bestIndexes.Where(kpv =>
                                                                   ((kpv.Value == BondAttachment.VGuide && bestDistX > distX) || (kpv.Value == BondAttachment.HGuide && bestDistY > distY))
                                                                   ).ToList())
                            {
                                bestIndexes.Remove(item.Key);
                            }

                            bestDistX = Math.Min(bestDistX, distX);
                            bestDistY = Math.Min(bestDistY, distY);
                            bestIndexes.Add(i, targ);
                        }
                    }
                    else if (targ == BondAttachment.VGuide) // clear non HGuides
                    {
                        if (distX - 0.0001f <= bestDistX)
                        {
                            foreach (var item in bestIndexes.Where(kpv => (kpv.Value.IsVGuide() && bestDistX > distX)).ToList())
                            {
                                bestIndexes.Remove(item.Key);
                            }

                            bestDistX = distX;
                            bestIndexes.Add(i, targ);
                        }
                    }
                    else if (targ == BondAttachment.HGuide) // clear non VGuides
                    {
                        if (distY - 0.0001f <= bestDistY)
                        {
                            foreach (var item in bestIndexes.Where(kpv => (kpv.Value.IsHGuide() && bestDistY > distY)).ToList())
                            {
                                bestIndexes.Remove(item.Key);
                            }

                            bestDistY = distY;
                            bestIndexes.Add(i, targ);
                        }
                    }
                }
            }

            // find offset
            bool hasSnap = false;

            Vex.Point target = Vex.Point.Empty;
            foreach (int key in bestIndexes.Keys)
            {
                hasSnap = true;
                BondAttachment bt  = bestIndexes[key];
                PointF         src = pts[key];
                target = (bt == BondAttachment.HGuide) ? snapsY[key] : snapsXP[key];
                if (bt.IsHandle())
                {
                    resultOffset = new Vex.Point(target.X - src.X, target.Y - src.Y);
                    break;
                }
                else if (bt == BondAttachment.CornerGuide)
                {
                    resultOffset = new Vex.Point(target.X - src.X, snapsY[key].Y - src.Y);
                    break;
                }
                else if (bt == BondAttachment.HGuide)
                {
                    if (resultOffset.X != 0)
                    {
                        resultOffset = new Vex.Point(resultOffset.X, target.Y - src.Y);
                        break;
                    }
                    resultOffset = new Vex.Point(0, target.Y - src.Y);
                }
                else if (bt == BondAttachment.VGuide)
                {
                    if (resultOffset.Y != 0)
                    {
                        resultOffset = new Vex.Point(target.X - src.X, resultOffset.Y);
                        break;
                    }
                    resultOffset = new Vex.Point(target.X - src.X, 0);
                }
            }

            // set snap points
            if (hasSnap)
            {
                foreach (int key in bestIndexes.Keys)
                {
                    BondAttachment bt = bestIndexes[key];
                    snapTypes[key] = bt;

                    target = (bt == BondAttachment.HGuide) ? snapsY[key] : snapsXP[key];
                    if (bt.IsHandle())
                    {
                        snapPoints[key] = new Vex.Point(target.X, target.Y);
                    }
                    else if (bt == BondAttachment.HGuide)
                    {
                        snapPoints[key] = new Vex.Point(pts[key].X + resultOffset.X, target.Y);
                    }
                    else if (bt == BondAttachment.VGuide)
                    {
                        snapPoints[key] = new Vex.Point(target.X, pts[key].Y + resultOffset.Y);
                    }
                    else if (bt == BondAttachment.CornerGuide)
                    {
                        snapPoints[key] = new Vex.Point(pts[key].X + resultOffset.X, pts[key].Y + resultOffset.Y);
                    }
                }
            }

            return(resultOffset);
        }