コード例 #1
0
ファイル: BLoop.cs プロジェクト: Reavenk/Berny_Core
        /// <summary>
        /// Inflate (dilate) the loop by a certain amount.
        /// </summary>
        /// <param name="amt">The distance to dialate the path contents.</param>
        /// <remarks>Use a negative amt value to deflate/erode.</remarks>
        public void Inflate(float amt)
        {
            Dictionary <BNode, InflationCache> cachedInf =
                new Dictionary <BNode, InflationCache>();

            // Go through all nodes and get their influences. We can't do this
            // on the same pass we update them, or else we would be modifying
            // values that would be evaluated later as dirty neighbors.
            foreach (BNode bn in this.nodes)
            {
                InflationCache ic = new InflationCache();
                bn.GetInflateDirection(out ic.selfInf, out ic.inInf, out ic.outInf);

                cachedInf.Add(bn, ic);
            }

            foreach (KeyValuePair <BNode, InflationCache> kvp in cachedInf)
            {
                BNode bn = kvp.Key;
                // This is just us being lazy for sanity. Sure we could try to
                // inflate while keeping smooth or symmetry, or it might just
                // naturally work itself out if we leave it alone - but I'd rather
                // take the easy way out on this for now.
                // (wleu)
                if (bn.tangentMode != BNode.TangentMode.Disconnected)
                {
                    bn.SetTangentDisconnected();
                }

                bn.Pos    += amt * kvp.Value.selfInf;
                bn.TanIn  += amt * (kvp.Value.inInf - kvp.Value.selfInf);
                bn.TanOut += amt * (kvp.Value.outInf - kvp.Value.selfInf);
            }
        }
コード例 #2
0
ファイル: Operators.cs プロジェクト: Reavenk/Berny_Core
        public static void Edgify(BLoop loop, float pushOut, float pullIn = 0.0f)
        {
            if (pushOut == 0.0f && pullIn == 0.0f)
            {
                return;
            }

            List <BNode> islands = loop.GetIslands();

            foreach (BNode bisl in islands)
            {
                // This will probably just give us bisl back, but it that's the case, then it should
                // be minimal overhead - just to be safe though, and to see what kind of connectivity we're dealing with.
                BNode.EndpointQuery eq = bisl.GetPathLeftmost();

                List <BNode>          origs      = new List <BNode>();
                List <BNode>          copies     = new List <BNode>();
                List <InflationCache> inflations = new List <InflationCache>();
                foreach (BNode it in eq.Enumerate())
                {
                    origs.Add(it);

                    BNode cpy = new BNode(loop, it, false, true);
                    copies.Add(cpy);

                    loop.nodes.Add(cpy);

                    InflationCache ic = new InflationCache();
                    it.GetInflateDirection(out ic.selfInf, out ic.inInf, out ic.outInf);
                    inflations.Add(ic);
                }

                // Stitch the new chain - it should have a reverse winding.
                //
                // The loop is a little backwards, but basically we sub instead of add to
                // treat the prev item in the array like the next in the chain.
                for (int i = 1; i < copies.Count; ++i)
                {
                    copies[i].next     = copies[i - 1];
                    copies[i - 1].prev = copies[i];
                }

                int lastIdx = copies.Count - 1;
                if (eq.result == BNode.EndpointResult.Cyclical)
                {
                    // If it was cyclical, it should close in on itself and it should
                    // never touch the original outline;
                    //
                    // Remember we're treating copies in reverse.
                    copies[lastIdx].prev = copies[0];
                    copies[0].next       = copies[lastIdx];
                }
                else
                {
                    // Or else the opposite ends connect to each other.
                    // Remember we're treating copies in reverse.
                    origs[0].prev  = copies[0];
                    copies[0].next = origs[0];

                    origs[lastIdx].next  = copies[lastIdx];
                    copies[lastIdx].prev = origs[lastIdx];

                    origs[0].UseTanIn        = false;
                    origs[lastIdx].UseTanOut = false;
                    copies[0].UseTanOut      = false;
                    copies[lastIdx].UseTanIn = false;
                }

                if (pushOut != 0.0f)
                {
                    // Now that we have copies and connectivity set up, it's time
                    // to apply the thickening
                    for (int i = 0; i < origs.Count; ++i)
                    {
                        // Push out the original
                        origs[i].Pos    += pushOut * inflations[i].selfInf;
                        origs[i].TanIn  += pushOut * (inflations[i].inInf - inflations[i].selfInf);
                        origs[i].TanOut += pushOut * (inflations[i].outInf - inflations[i].selfInf);
                    }
                }

                if (pullIn != 0.0f)
                {
                    // We can optionally pull in the copy
                    for (int i = 0; i < copies.Count; ++i)
                    {
                        copies[i].Pos    += pullIn * inflations[i].selfInf;
                        copies[i].TanIn  += pullIn * (inflations[i].inInf - inflations[i].selfInf);
                        copies[i].TanOut += pullIn * (inflations[i].outInf - inflations[i].selfInf);
                    }
                }
            }
        }