예제 #1
0
        // TODO: Consider a more sophisticated gradient function, as it recommends in the paper.
        // But for now, I can't imagine subpixel accuracy is going to make a whole lot of difference.
        private static vFloat GradientAtPoint(this IField2d <float> field, vFloat point)
        {
            int   pX = (int)point[0];
            int   pY = (int)point[1];
            float x, y;

            if (pX % 2 == 1 || pX == field.Width - 1)
            {
                x = field[pY, pX - 1] - field[pY, pX];
            }
            else
            {
                x = field[pY, pX] - field[pY, pX + 1];
            }

            if (pY % 2 == 1 || pY == field.Height - 1)
            {
                y = field[pY - 1, pX] - field[pY, pX];
            }
            else
            {
                y = field[pY, pX] - field[pY + 1, pX];
            }

            return(new vFloat(x, y));
        }
예제 #2
0
        private List <vFloat> BuildSplinesRecursively(TreeNode <Point2d> node, vFloat parentPoint)
        {
            vFloat herePoint = new vFloat(
                node.value.x + (float)this.random.NextDouble(), // X position in world coordinates
                node.value.y + (float)this.random.NextDouble(), // Y position in world coordinates
                this.altitudes[node.value.y, node.value.x],     // altitude in whatever units were used by the "altitudes" input
                node.Size() / CAPACITY_DIVISOR);                // river size, meaning the count of pixels above this, divided to avoid affecting the spline

            if (node.children.Count == 0 || (node.children.Count > 1 && node.Depth() <= minSizeForFork))
            {
                // Idiotic case, tree has only one element and a spline is ridiculous.
                if (node.parent == null)
                {
                    throw new ArgumentException("A tree with only one node cannot be made into a spline tree.");
                }

                List <vFloat> lst = new List <vFloat>();
                lst.Add(2 * herePoint - parentPoint);
                lst.Add(herePoint);
                return(lst);
            }
            else if (node.children.Count == 1)
            {
                // We know there's only one because we just checked; we just use this syntax to get that one out of the children.
                foreach (var child in node.children)
                {
                    List <vFloat> lst = BuildSplinesRecursively(child, herePoint);
                    lst.Add(herePoint);
                    return(lst);
                }
                throw new InvalidOperationException("A non-empty list behaved as if it was empty.  Has a race condition been introduced?");
            }
            else
            {
                List <List <vFloat> > lsts = new List <List <vFloat> >();

                int minIdx = 0;
                foreach (var n in node.children)
                {
                    if (n.Size() < minSizeForFork)
                    {
                        continue;
                    }

                    lsts.Add(BuildSplinesRecursively(n, herePoint));
                    lsts[lsts.Count - 1].Add(herePoint);

                    if (lsts[lsts.Count - 1].Count < lsts[minIdx].Count)
                    {
                        minIdx = lsts.Count - 1;
                    }
                }

                if (parentPoint == null)
                {
                    parentPoint = GetParentPoint(lsts[minIdx]);
                }

                for (int idx = 0; idx < lsts.Count; idx++)
                {
                    if (idx != minIdx)
                    {
                        lsts[idx].Add(parentPoint);
                        lsts[idx].Add(2 * lsts[idx][lsts[idx].Count - 2] - parentPoint);
                        this.splines.Add(new CenCatRomSpline(lsts[idx].ToArray(), this.alpha));
                    }
                }

                return(lsts[minIdx]);
            }
        }