コード例 #1
0
        LinkedList <MetroEdge> SortAdjacentEdges(int v, List <MetroEdge> adjacent)
        {
            MetroEdge mn  = adjacent.First();
            int       mnv = OppositeNode(mn, v);

            adjacent.Sort(delegate(MetroEdge edge1, MetroEdge edge2) {
                int a = OppositeNode(edge1, v);
                int b = OppositeNode(edge2, v);

                //TODO: remove angles!
                double angA = Point.Angle(positions[a] - positions[v], positions[mnv] - positions[v]);
                double angB = Point.Angle(positions[b] - positions[v], positions[mnv] - positions[v]);

                return(angA.CompareTo(angB));
            });

            LinkedList <MetroEdge> res = new LinkedList <MetroEdge>();

            foreach (MetroEdge edge in adjacent)
            {
                LinkedListNode <MetroEdge> node = res.AddLast(edge);
                adjacencyIndex.Add(new Tuple <int, MetroEdge>(v, edge), node);
            }
            return(res);
        }
コード例 #2
0
        /// <summary>
        /// offsets the curve in the given direction
        /// </summary>
        /// <param name="offset">the width of the offset</param>
        /// <param name="dir">the direction of the offset</param>
        /// <returns></returns>
        public ICurve OffsetCurve(double offset, Point dir)
        {
            //is dir inside or outside
            Point  d     = dir - center;
            double angle = Point.Angle(aAxis, d);
            Point  s     = aAxis * Math.Cos(angle) + bAxis * Math.Sin(angle);

            if (s.Length < d.Length)
            {
                double al = aAxis.Length;
                double bl = bAxis.Length;
                return(new Ellipse((al + offset) * aAxis.Normalize(), (bl + offset) * bAxis.Normalize(), center));
            }
            {
                double al = aAxis.Length;
                double bl = bAxis.Length;
#if DEBUGCURVES
                if (al < offset || bl < offset)
                {
                    throw new Exception("wrong parameter for ellipse offset");
                }
#endif
                return(new Ellipse((al - offset) * aAxis.Normalize(), (bl - offset) * bAxis.Normalize(), center));
            }
        }
コード例 #3
0
        static Dictionary <GeomEdge, double> GetMiddleAnglesOfMultiedge(List <GeomEdge> multiedge, GeomNode node)
        {
            var      ret       = new Dictionary <GeomEdge, double>();
            GeomEdge firstEdge = multiedge[0];

            Point a = node.Center;
            Point b = Middle(firstEdge.Curve);

            ret[firstEdge] = 0;

            for (int i = 1; i < multiedge.Count; i++)
            {
                GeomEdge edge  = multiedge[i];
                Point    c     = Middle(edge.Curve);
                double   angle = Point.Angle(b, a, c);
                if (angle > Math.PI)
                {
                    angle = angle - Math.PI * 2;
                }

                ret[edge] = angle;
            }

            return(ret);
        }
コード例 #4
0
        bool AngleIsTooSmallAfterShortcutAtVertex(VisibilityVertex v1, VisibilityVertex v2, VisibilityVertex v3)
        {
            foreach (var edge in v1.OutEdges)
            {
                var t = edge.Target;
                if (t == v3 || t == v2)
                {
                    continue;
                }
                //LayoutAlgorithmSettings.ShowDebugCurves(new DebugCurve(1, "red", new LineSegment(v3.Point, v1.Point)),
                //new DebugCurve(1, "blue", new LineSegment(v1.Point, t.Point)));
                if (AngleIsTooSmall(Point.Angle(v3.Point, v1.Point, t.Point)))
                {
                    return(true);
                }
            }

            foreach (var edge in v1.InEdges)
            {
                var t = edge.Source;
                if (t == v3 || t == v2)
                {
                    continue;
                }

                if (AngleIsTooSmall(Point.Angle(v3.Point, v1.Point, t.Point)))
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #5
0
        /// <summary>
        /// Computes the standard deviation of the edge length change for a set of given edges.
        /// </summary>
        /// <param name="graphOld"></param>
        /// <param name="graphNew"></param>
        /// <param name="proximityEdges"></param>
        /// <returns></returns>
        public static Tuple <String, double> RotationAngleMean(GeometryGraph graphOld, GeometryGraph graphNew,
                                                               HashSet <Tuple <int, int> > proximityEdges)
        {
            if (proximityEdges.Count == 0)
            {
                return(Tuple.Create("RotationAngleMean", -1.0));
            }
            double meanRotationAngle = 0;
            int    n = proximityEdges.Count;

            foreach (var p in proximityEdges)
            {
                var oldDir = graphOld.Nodes[p.Item1].Center - graphOld.Nodes[p.Item2].Center;
                var newDir = graphNew.Nodes[p.Item1].Center - graphNew.Nodes[p.Item2].Center;

                double angle = Point.Angle(oldDir, newDir);
                Debug.Assert(angle >= 0);
                if (angle > Math.PI)
                {
                    angle = 2 * Math.PI - angle;
                }
                Debug.Assert(angle >= 0);
                meanRotationAngle += angle;
            }
            meanRotationAngle /= n;
            meanRotationAngle *= (180 / Math.PI);


            return(Tuple.Create("RotationAngleMean", meanRotationAngle));
        }
コード例 #6
0
ファイル: HubRadiiCalculator.cs プロジェクト: Caliper/MSAGL
        /// <summary>
        /// Radius we need to draw to separate adjacent bundles ab and ac
        /// </summary>
        internal static double GetMinRadiusForTwoAdjacentBundles(double r, Point a, Point b, Point c, double widthAB, double widthAC,
                                                                 MetroGraphData metroGraphData, BundlingSettings bundlingSettings)
        {
            if (widthAB < ApproximateComparer.DistanceEpsilon || widthAC < ApproximateComparer.DistanceEpsilon)
            {
                return(r);
            }

            double angle = Point.Angle(b, a, c);

            angle = Math.Min(angle, Math.PI * 2 - angle);
            if (angle < ApproximateComparer.DistanceEpsilon)
            {
                return(2 * bundlingSettings.MaxHubRadius);
            }

            if (angle >= Math.PI / 2)
            {
                return(r * 1.05);
            }

            //find the intersection point of two bundles
            double sina = Math.Sin(angle);
            double cosa = Math.Cos(angle);
            double aa   = widthAB / (4 * sina);
            double bb   = widthAC / (4 * sina);
            double d    = 2 * Math.Sqrt(aa * aa + bb * bb + 2 * aa * bb * cosa);

            d = Math.Min(d, 2 * bundlingSettings.MaxHubRadius);
            d = Math.Max(d, r);
            return(d);
        }
コード例 #7
0
        string EllipseToString(Ellipse ellipse)
        {
            string largeArc = Math.Abs(ellipse.ParEnd-ellipse.ParStart) >= Math.PI? "1":"0";
            string sweepFlag= ellipse.OrientedCounterclockwise()?"1":"0";

            return String.Join(" ", "A", EllipseRadiuses(ellipse), DoubleToString(Point.Angle(new Point(1, 0), ellipse.AxisA) / (Math.PI / 180.0)), largeArc, sweepFlag, PointsToString(ellipse.End));
        }
コード例 #8
0
        //private void ProcessLeftSideOfTrapez(ref int p1, ref int p2, ref int q2, ref int q1) {
        //    //the closest vertex is on the left side
        //    Point pn1 = P.Pnt(p1); Point pn2 = P.Pnt(p2);
        //    Point qn1 = Q.Pnt(q1); Point qn2 = Q.Pnt(q2);

        //   //SugiyamaLayoutSettings.Show(new LineSegment(pn1, pn2), new LineSegment(pn2, qn2), new LineSegment(qn2, qn1), new LineSegment(qn1, pn1));
        //    double ap1 = Point.Angle(pn2, pn1, qn1);
        //    double aq1 = Point.Angle(pn1, qn1, qn2);
        //    System.Diagnostics.Debug.Assert(ap1 + aq1 >= Math.PI);
        //    //the point is on the left side
        //    if (ap1 >= Math.PI / 2 && aq1 >= Math.PI / 2) {
        //        q2 = q1; //the vertices of the left side gives the solution
        //        p2 = p1;
        //    } else if (ap1 < Math.PI / 2) {
        //        q2 = q1;
        //        if (!Point.CanProject(qn1, pn1, pn2))
        //            p1 = p2;
        //    } else { //aq1<Pi/2
        //        p2 = p1;
        //        if (!Point.CanProject(pn1, qn1, qn2))
        //            q1 = q2;
        //    }
        //}


        void GetAnglesAtTheMedian(int mp, int mq, ref Point mP, ref Point mQ, out double a1, out double a2,
                                  out double b1, out double b2)
        {
            a1 = Point.Angle(mQ, mP, P.Pnt(P.Prev(mp)));
            a2 = Point.Angle(P.Pnt(P.Next(mp)), mP, mQ);
            b1 = Point.Angle(Q.Pnt(Q.Next(mq)), mQ, mP);
            b2 = Point.Angle(mP, mQ, Q.Pnt(Q.Prev(mq)));
        }
コード例 #9
0
        int CompareByAngleFromNodeCenter(VisibilityVertex a, VisibilityVertex b, Point center)
        {
            var x      = new Point(1, 0);
            var aAngle = Point.Angle(x, a.Point - center);
            var bAngle = Point.Angle(x, b.Point - center);

            return(aAngle.CompareTo(bAngle));
        }
コード例 #10
0
        void ModifyEdgeByScale(Point delta, GeomEdge edge)
        {
            //StraightLineEdges.CreateSimpleEdgeCurveWithUnderlyingPolyline(edge);
            var sn = edge.Source.UserData as Drawing.Node;
            var tn = edge.Target.UserData as Drawing.Node;

            //var gg = graph.UserData as Graph;
            //var vsn = Viewer.GetIViewerObject(sn);
            //var vtn = Viewer.GetIViewerObject(tn);
            Drawing.Node oN = null, tN = null;
            if (Viewer.GetIViewerObject(sn).MarkedForDragging)
            {
                tN = sn;
                oN = tn;
            }
            else
            {
                tN = tn;
                oN = sn;
            }
            Point  o = oN.Pos, t = tN.Pos, t_ = t - delta;
            double scale = (t - o).Length / (t_ - o).Length;
            //double angle = Point.Angle(t, o, t_)*180/Math.PI;
            double angle = Point.Angle(t, o, t_);

            System.Windows.Media.Matrix mm = System.Windows.Media.Matrix.Identity;
            //mm.ScaleAt(scale, scale, o.X, o.Y);
            mm.RotateAt(angle, o.X, o.Y);
            //PlaneTransformation mt = new PlaneTransformation(mm.M11,mm.M12,mm.OffsetX,mm.M21,mm.M22,mm.OffsetY);
            var scaleMatrix       = new PlaneTransformation(scale, 0, 0, 0, scale, 0);
            var translateToOrigin = new PlaneTransformation(1, 0, -o.X, 0, 1, -o.Y);
            var translateToNode   = new PlaneTransformation(1, 0, o.X, 0, 1, o.Y);
            var rotateMatrix      = PlaneTransformation.Rotation(-angle);
            var matrix            = translateToNode * scaleMatrix * rotateMatrix * translateToOrigin;

            if (edge.UnderlyingPolyline != null)
            {
                var ul = edge.UnderlyingPolyline;
                if (tN == sn)
                {
                    ul.HeadSite.Point = t;
                }
                else
                {
                    ul.LastSite.Point = t;
                }
                for (Site s = ul.HeadSite.Next; s != ul.LastSite; s = s.Next)
                {
                    s.Point = matrix * s.Point;
                }
                edge.Curve = ul.CreateCurve();
                Arrowheads.TrimSplineAndCalculateArrowheads(edge, edge.Curve, true, false);
            }

            //edge.Curve = edge.Curve.Transform(matrix);

            //var angle= Point.Angle(graph.)
        }
コード例 #11
0
        private Func <int, double> GetSequenceDelegate(Point point)
        {
            Point pointOfP = Pnt(0);

            return(delegate(int i) {
                double d = Point.Angle(pointOfP, point, Pnt(i));
                return d < Math.PI ? d : d - 2 * Math.PI;
            });
        }
コード例 #12
0
        static void SortPointByAngles(LgNodeInfo nodeInfo, Point[] polySplitArray)
        {
            var angles = new double[polySplitArray.Length];

            for (int i = 0; i < polySplitArray.Length; i++)
            {
                angles[i] = Point.Angle(new Point(1, 0), polySplitArray[i] - nodeInfo.Center);
            }
            Array.Sort(angles, polySplitArray);
        }
コード例 #13
0
        void SnapToAfterBefore(VisibilityVertex v, RbTree <VisibilityVertex> nodeBoundaryRbTree, Point center, Dictionary <VisibilityEdge, VisibilityVertex> ret, VisibilityEdge e)
        {
            VisibilityVertex beforeV, afterV;

            FindBeforeAfterV(v, nodeBoundaryRbTree, out beforeV, out afterV, center);
            var beforeAngle = Point.Angle(beforeV.Point - center, v.Point - center);
            var afterAngle  = Point.Angle(v.Point - center, afterV.Point - center);

            ret[e] = beforeAngle <= afterAngle ? beforeV : afterV;
        }
コード例 #14
0
        void FindBeforeAfterV(VisibilityVertex v, RbTree <VisibilityVertex> nodeBoundaryRbTree,
                              out VisibilityVertex beforeV, out VisibilityVertex afterV, Point center)
        {
            Point xDir   = new Point(1, 0);
            var   vAngle = Point.Angle(xDir, v.Point - center);
            var   rNode  = nodeBoundaryRbTree.FindLast(w => Point.Angle(xDir, w.Point - center) <= vAngle);

            beforeV = rNode != null ? rNode.Item : nodeBoundaryRbTree.TreeMaximum().Item;
            rNode   = nodeBoundaryRbTree.FindFirst(w => Point.Angle(xDir, w.Point - center) >= vAngle);
            afterV  = rNode != null ? rNode.Item : nodeBoundaryRbTree.TreeMinimum().Item;
        }
コード例 #15
0
        public static Polyline RemoveLeastSignificantVertices(this Polyline polyline, double smallestAcceptableAngle = Tolerance.Angle, double angleTolerance = Tolerance.Angle, double distanceTolerance = Tolerance.Distance)
        {
            List <Point> pnts = polyline.DiscontinuityPoints(distanceTolerance, angleTolerance);
            Point        originalLastPoint = pnts.Last();

            int startIndex = 0;
            int maxIndex   = polyline.IsClosed(distanceTolerance) ? pnts.Count : pnts.Count - 2;

            while (startIndex < maxIndex)
            {
                Point first  = pnts[startIndex];
                Point second = pnts[(startIndex + 1) % pnts.Count];
                Point third  = pnts[(startIndex + 2) % pnts.Count];

                if (first.Angle(second, third) <= smallestAcceptableAngle)
                {
                    pnts.RemoveAt((startIndex + 1) % pnts.Count);  //Delete the second point from the list, it's not necessary
                    maxIndex--;
                }
                else
                {
                    startIndex++; //Move onto the next point
                }
            }

            if (polyline.IsClosed(distanceTolerance)) //Only re-close if original polyline is closed
            {
                pnts.Add(pnts.First());
            }

            Polyline pLine = new Polyline()
            {
                ControlPoints = pnts,
            };

            List <double> angles = new List <double>();

            foreach (BH.oM.Geometry.Point point in pnts)
            {
                double angle = point.Angle(pnts[(pnts.IndexOf(point) + 1) % pnts.Count], pnts[(pnts.IndexOf(point) + 2) % pnts.Count]);
                angles.Add(angle);
            }
            foreach (double angle in angles)
            {
                if (angle < smallestAcceptableAngle)
                {
                    BH.Engine.Reflection.Compute.RecordWarning("One ore more of the angles of the new polyline is smaller than smallestAcceptableAngle, choose a smaller value for smallestAcceptableAngle or proceed with the created polyline as it is.");
                }
            }

            return(pLine);
        }
コード例 #16
0
ファイル: Polygon.cs プロジェクト: mbdevpl/BitmapEditor
        //public void Rotate(double originX, double originY, double angle);

        public void Rotate(Point origin, double angle)
        {
            double distanceToOrigin;
            double angleToOrigin;

            for (int i = 0; i < PointsCount; ++i)
            {
                Point pt = points[i];

                distanceToOrigin = pt.Distance(origin);
                angleToOrigin    = pt.Angle(origin);

                points[i] = origin.MoveTo(angleToOrigin - 180 + angle, distanceToOrigin);
            }
        }
コード例 #17
0
        public static Polyline CleanPolyline(this Polyline polyline, double tolerance = Tolerance.Angle)
        {
            //This method is for closed polylines only at the moment
            if (!polyline.IsClosed())
            {
                BH.Engine.Reflection.Compute.RecordError("The CleanPolyline method is only for closed polylines and the input polyline is not closed.");
                return(polyline);
            }

            List <Point> pnts = polyline.DiscontinuityPoints();

            if (pnts.Count < 3)
            {
                return(polyline);                //If there's only two points here then this method isn't necessary
            }
            int startIndex = 0;

            while (startIndex < pnts.Count)
            {
                Point first  = pnts[startIndex];
                Point second = pnts[(startIndex + 1) % pnts.Count];
                Point third  = pnts[(startIndex + 2) % pnts.Count];

                if (first.Angle(second, third) <= BH.oM.Geometry.Tolerance.Angle)
                {
                    //Delete the second point from the list, it's not necessary
                    pnts.RemoveAt((startIndex + 1) % pnts.Count);
                }
                else
                {
                    startIndex++; //Move onto the next point
                }
            }

            if (pnts.First() != pnts.Last())
            {
                pnts.Add(pnts.First()); //Reclose polyline
            }
            Polyline pLine = new Polyline()
            {
                ControlPoints = pnts,
            };

            return(pLine);
        }
コード例 #18
0
        void TryToGlueEdges(Station node, Station a, Station b, Dictionary <Tuple <Station, Station>, Point> gluedEdges, int step)
        {
            Debug.Assert(a != b);
            var angle = Point.Angle(a.Position, node.Position, b.Position);

            if (angle < bundlingSettings.AngleThreshold)
            {
                var    la    = (a.Position - node.Position).Length;
                var    lb    = (b.Position - node.Position).Length;
                double ratio = Math.Min(la, lb) / Math.Max(la, lb);
                if (ratio < 0.05)
                {
                    return;
                }

                if (la < lb)
                {
                    if (EdgeGluingIsAllowed(node, a, b))
                    {
                        AddEdgeToGlue(node, b, a, a.Position, gluedEdges);
                        return;
                    }
                }
                else
                {
                    if (EdgeGluingIsAllowed(node, b, a))
                    {
                        AddEdgeToGlue(node, a, b, b.Position, gluedEdges);
                        return;
                    }
                }

                //TODO: need this???
                if (step < 5 && ratio > 0.5)
                {
                    Point newPosition = ConstructGluingPoint(node, a, b);
                    if (EdgeGluingIsAllowed(node, a, b, newPosition))
                    {
                        AddEdgeToGlue(node, b, a, newPosition, gluedEdges);
                    }
                }
            }
        }
コード例 #19
0
ファイル: Obstacle.cs プロジェクト: suprcodr/EFDesigner
        // Internal for testing
        internal void ConvertToRectangleIfClose()
        {
            if (this.PaddedPolyline.PolylinePoints.Count() != 4)
            {
                return;
            }

            // We're not a rectangle now but that may be due to rounding error, so we may be close to one.
            // First check that it's close to an axis.
            var          ppt       = this.PaddedPolyline.StartPoint;
            var          nextPpt   = ppt.NextOnPolyline;
            var          testPoint = ppt.Point - nextPpt.Point;
            var          slope     = ((testPoint.X == 0) || (testPoint.Y == 0)) ? 0 : Math.Abs(testPoint.Y / testPoint.X);
            const double factor    = 1000.0;

            if ((slope < factor) && (slope > (1.0 / factor)))
            {
                return;
            }

            const double radian90     = 90.0 * (Math.PI / 180.0);
            const double maxAngleDiff = radian90 / factor;

            // Now check angles.
            do
            {
                var nextNextPpt = nextPpt.NextOnPolyline;
                var angle       = Point.Angle(ppt.Point, nextPpt.Point, nextNextPpt.Point);
                if (Math.Abs(radian90 - angle) > maxAngleDiff)
                {
                    return;
                }

                ppt     = nextPpt;
                nextPpt = nextNextPpt;
            } while (ppt != this.PaddedPolyline.StartPoint);

            this.PaddedPolyline = Curve.PolyFromBox(this.PaddedPolyline.BoundingBox);
            this.IsRectangle    = true;
            Debug.Assert(this.IsPolylineRectangle(), "PaddedPolyline is not rectangular");
            return;
        }
コード例 #20
0
        string EllipticalArcToString(Ellipse ellipse)
        {
            /*
             * rx ry x-axis-rotation large-arc-flag sweep-flag x y
             * */
            //In general in an Msagl ellipse the axes don't have to be orthogonal: we have a possible bug here
            var rx            = "A" + DoubleToString(ellipse.AxisA.Length);
            var ry            = DoubleToString(ellipse.AxisB.Length);
            var xAxisRotation = DoubleToString(180 * Point.Angle(new Point(1, 0), ellipse.AxisA) / Math.PI);
            var largeArcFlag  = Math.Abs(ellipse.ParEnd - ellipse.ParStart) >= Math.PI ? "1" : "0";
            var sweepFlagInt  = ellipse.ParEnd > ellipse.ParStart ? 1 : 0; //it happens because of the y-axis orientation down in SVG

            if (AxesSwapped(ellipse.AxisA, ellipse.AxisB))
            {
                sweepFlagInt = sweepFlagInt == 1 ? 0 : 1;
            }
            var endPoint = PointToString(ellipse.End);

            return(string.Join(" ", new[] { rx, ry, xAxisRotation, largeArcFlag, sweepFlagInt.ToString(), endPoint }));
        }
コード例 #21
0
ファイル: HubRadiiCalculator.cs プロジェクト: Caliper/MSAGL
        /// <summary>
        /// Radius we need to draw two adjacent bundles ab and ac
        /// </summary>
        internal static double GetMinRadiusForTwoAdjacentBundlesOld(double r, Point a, Point b, Point c, double widthAB, double widthAC,
                                                                    MetroGraphData metroGraphData, BundlingSettings bundlingSettings)
        {
            if (widthAB < ApproximateComparer.DistanceEpsilon || widthAC < ApproximateComparer.DistanceEpsilon)
            {
                return(r);
            }

            double angle = Point.Angle(b, a, c);

            angle = Math.Min(angle, Math.PI * 2 - angle);
            if (angle < ApproximateComparer.DistanceEpsilon)
            {
                return(2 * bundlingSettings.MaxHubRadius);
            }

            //binary search
            //TODO: solve the equation
            double L = r;
            double R = 2 * bundlingSettings.MaxHubRadius;

            while (Math.Abs(R - L) > 0.1)
            {
                double C = (L + R) / 2;

                double alpha0 = Math.Asin(widthAB / (2 * C));
                double alpha1 = Math.Asin(widthAC / (2 * C));
                if (alpha0 + alpha1 <= angle)
                {
                    R = C;
                }
                else
                {
                    L = C;
                }
            }

            return(L);
        }
コード例 #22
0
        double GetBaseMiddleParamInDirection(BundleBase targetBase, Point sPos, Point neighbPos)
        {
            var curve  = targetBase.Curve;
            var circle = curve as Ellipse;

            if (circle != null && circle.IsArc())
            {
                return(Point.Angle(circle.AxisA, neighbPos - sPos));
            }

            var intersections = Curve.GetAllIntersections(curve, new LineSegment(sPos, neighbPos), true);

            foreach (var intersectionInfo in intersections)
            {
                var xP = intersectionInfo.IntersectionPoint;
                if ((xP - sPos) * (xP - neighbPos) <= 0)
                {
                    return(intersectionInfo.Par0);
                }
            }

            throw new InvalidOperationException();
        }
コード例 #23
0
        private bool VelocityChanged(Point PuckVold, Point PuckVnew)
        {
            Point oldVelocity = PuckVold.Normalize();
            Point newVelocity = PuckVnew.Normalize();


            if ((PuckVnew.Norm() <= PuckVold.Norm()) && (PuckVnew.Norm() >= 0.95 * PuckVold.Norm()) && (Math.Abs(PuckVnew.Angle() - PuckVold.Angle()) < 0.06))
            {
                return(false);
            }
            return(true);
        }