コード例 #1
0
        private static LinkedList <Circle> InitFrontchain(UiInnerNode node)
        {
            var frontChain = new LinkedList <Circle>();

            if (node.Children.Count == 0)
            {
                return(frontChain);
            }

            var c1 = node.Children[0].Circle;

            frontChain.AddLast(c1);

            if (node.Children.Count == 1)
            {
                return(frontChain);
            }

            var c2 = node.Children[1].Circle;

            c2.Position.Value = TreeGeometry.CalcTangentCircleCenter(c1.Position.Value, c1.Radius,
                                                                     c2.Radius,
                                                                     TreeGeometry.GetRandomAngle());
            frontChain.AddLast(c2);

            return(frontChain);
        }
コード例 #2
0
        private void DistributeSunflower(UiInnerNode innerNode, Transform parent)
        {
            var rndAngle = TreeGeometry.GetRandomAngle();

            for (var i = 0; i < innerNode.Children.Count; i++)
            {
                var child      = innerNode.Children[i];
                var nodeObject = AddChildContainer(child, parent, i, rndAngle);

                GenerateBranches(child, nodeObject.transform);
            }

            innerNode.Circle.Radius = innerNode.Children.Count == 1
                ? TreeGeometry.NodeDistanceFactor
                : TreeGeometry.CalcSunflowerRadius(innerNode.Children.Count - 1);
        }
コード例 #3
0
        /// <summary>
        /// From Wang's circle packing algorithm, see "Visualization of large hierarchical data by circle packing"
        /// </summary>
        /// <param name="innerNode"></param>
        internal LinkedList <Circle> CirclePacking(UiInnerNode innerNode)
        {
            var frontChain = InitFrontchain(innerNode);

            for (var i = 2; i < innerNode.Children.Count; i++)
            {
                // circle with minimal distance to origin
                var tangentCircle1 = GetClosestFromOrigin(frontChain);

                // circle after tangent circle 1
                var tangentCircle2 = tangentCircle1.Next();

                // circle of current inner node, claculate potential position
                var currentCircleRad = innerNode.Children[i].Circle.Radius;
                var currentCirclePos = TreeGeometry.CalcTangentCircleCenter(tangentCircle1.Value.Position.Value,
                                                                            tangentCircle2.Value.Position.Value, tangentCircle1.Value.Radius, tangentCircle2.Value.Radius,
                                                                            currentCircleRad);

                // circle that intersects current circle
                var intersectingCircle = GetIntersectingCircle(frontChain, currentCirclePos, currentCircleRad);

                // No intersection, place current circle
                if (intersectingCircle == null)
                {
                    innerNode.Children[i].Circle.Position.Value = currentCirclePos;
                    frontChain.AddBefore(tangentCircle2, innerNode.Children[i].Circle);
                    continue;
                }

                // Delete old circles from front chain
                if (intersectingCircle.IsAfter(tangentCircle2))
                {
                    tangentCircle1.DeleteAfterUntil(intersectingCircle);
                }
                else
                {
                    intersectingCircle.DeleteAfterUntil(tangentCircle2);
                }

                // Proceed with current circle again, position is calculated according to updated front chain
                i--;
            }

            innerNode.Circle.Radius = GetEnclosingRadius(frontChain);

            return(frontChain);
        }
コード例 #4
0
        private GameObject AddChildContainer(UiNode node, Transform parent, int n, float initialPhi = 0)
        {
            //////////////////////////////////
            //                              //
            //         y                    //
            //         ∧                    //
            //         | .  r               //
            //         |   ˙ .              //
            //         |       ˙ . node     //
            //         |__˛   ‚´ .          //
            //         | θ \‚´   .          //
            //         |  ‚´ l   .          //
            //         |‚´       .          //
            //  parent ˚-. ------.--> x     //
            //        / φ  ˙ .   .          //
            //       /————´    ˙ .          //
            //      ⩗                       //
            //    - z                       //
            //                              //
            //////////////////////////////////

            var r            = TreeGeometry.CalcSunflowerRadius(n);
            var phi          = TreeGeometry.CalcPhi(n, initialPhi);
            var theta        = TreeGeometry.CalcTheta(manipulator.DefaultEdgeHeight, r);
            var l            = TreeGeometry.CalcEdgeLength(manipulator.DefaultEdgeHeight, theta);
            var nodePosition = TreeGeometry.CalcNodePosition(l, theta, phi);

            var branchObject = manipulator.AddEmptyBranchObject(parent);
            var edgeObject   = manipulator.AddEdgeObject(branchObject.transform,
                                                         TreeGeometry.SizeToScale(l, manipulator.DefaultEdgeHeight, manipulator.DefaultEdgeScale.y),
                                                         theta,
                                                         phi);
            var nodeObject =
                manipulator.AddEmptyNodeObject(node, branchObject.transform, nodePosition, edgeObject);

            return(nodeObject);
        }
コード例 #5
0
 private static LinkedListNode <Circle> GetIntersectingCircle(LinkedList <Circle> frontChain, Vector2 position,
                                                              float radius)
 {
     return(frontChain.Find(frontChain.FirstOrDefault(
                                c => TreeGeometry.Intersects(c.Position.Value, position, c.Radius, radius))));
 }