开发者

Why is my dragon fractal incomplete [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center. Closed 11 years ago.

I have translated the code from javascript to c# which can be found by going to this excellent demo at http://fractal.qfox.nl/dragon.js

My translation is intended to produce just a single dragon upon clicking the button but I think I have missed something in my version.

See the Wikipedia article: Dragon Curve for more information.

Incomplete dragon fractal output:

Why is my dragon fractal incomplete [closed]

Code:

public partial class MainPage : UserControl
{
    PointCollection pc;

    Int32[] pattern = new Int32[] { 1, 1, 0, 2, 1, 0, 0, 3 };
    Int32[] position = new Int32[] { 0, 0, 0, 0, 0, 0, 0, 0 };
    Boolean toggle;
    Char r = default(Char);

    Int32 distance = 10; // line length
    Int32 step = 100; // paints per step
    Int32 skip = 10; // folds per paint

    Double x = 0;
    Double y = 0;
    Int32 a = 90;


    public MainPage()
    {
        InitializeComponent();
    }


    private void btnFire_Click(object sender, RoutedEventArgs e)
    {

        x = canvas.ActualWidth / 3;
        y = canvas.ActualHeight / 1.5;

        pc = new PointCollection();

        var n = step;
        while (--n > 0)
        {
            List<Char> s = getS(skip);
            draw(s);
        }

        Polyline p = new Polyline();
        p.Stroke = new SolidColorBrush(Colors.Red);
        p.StrokeThickness = 0.5;

        p.Points = pc;
        canvas.Children.Add(p);
    }


    List<Char> getS(Int32 n)
    {
        List<Char> s1 = new List<Char>();
        while (n-- > 0) s1.Add(getNext(0));
        return s1;
    }


    void draw(List<Char> s)
    {        
        pc.Add(new Point(x, y));
        for (Int32 i = 0, n = s.Count; i < n; i++)
        {
            pc.Add(new Point(x, y));
            Int32 j;
            if (int.TryParse(s[i].ToString(), out j) && j != 0)
            {
                if ((a + 90) % 360 != 0)
                {
                    a = (a + 90) % 360;
                }
                else
                {
                    a = 360; // Right
                }
            }
            else
            {
                if (a - 90 != 0)
                {
                    a = a - 90;
                }
                else
                {
                    a = 360; // Right
                }
            }
            // new target
            if (a == 0 || a == 360)
            {
                y -= distance;
            }
            else if (a == 90)
            {
                x += distance;
            }
            else if (a == 180)
            {
                y += distance;
            }
            else if (a == 270)
            {
                x -= distance;
            }

            // move
            pc.Add(new Point(x, y));
        }

    }

    Char getNext(Int32 n)
    {
        if (position[n] == 7)
        {
            r = getNext(n + 1);
            position[n] = 0;
        }
        else
        {
            var x = position[n] > 0 ? pattern[position[n]] : pattern[0];

            switch (x)
            {
                case 0:
                    r = '0';
                    break;
                case 1:
                    r = '1';
                    break;
                case 2:
                    if (!toggle)
                    {
                        r = '1';
                    }
                    else
                    {
                        r = '0';
                    }
                    toggle = !toggle;
                    b开发者_如何学JAVAreak;
            }
            position[n] = position[n] + 1;                
        }

        return r;
    }

}


I cleaned up the code, and tried to get how the pattern and position arrays should work to produce the correct sequence, but I couldn't figure it out. The last item in the pattern array is for example never used...

There is however a simpler method implementing the getNext method using just a counter:

bool getNext() {
  cnt++;
  return (cnt & ((cnt & -cnt) << 1)) != 0;
}

I have used that method before (about 20 years ago), and I found this implementation on the dragon curve wikipedia page.

The cleaned up code with this getNext implementation looks like this:

public partial class MainPage : UserControl {
    PointCollection pc;

    int cnt = 0;

    int distance = 10; // line length
    int steps = 1024; // number of paints

    int x = 0;
    int y = 0;
    int a = 90;


    public MainPage() {
        InitializeComponent();
    }


    private void btnFire_Click(object sender, RoutedEventArgs e) {

        x = (int)(canvas.ActualWidth / 3);
        y = (int)(canvas.ActualHeight / 1.5);

        pc = new PointCollection();

        draw(getS(steps));

        Polyline p = new Polyline();
        p.Stroke = new SolidColorBrush(Colors.Red);
        p.StrokeThickness = 0.5;

        p.Points = pc;
        canvas.Children.Add(p);
    }


    List<bool> getS(int n) {
        List<bool> s1 = new List<bool>();
        while (n-- > 0) {
            s1.Add(getNext());
        }
        return s1;
    }


    void draw(List<bool> s) {
        pc.Add(new Point(x, y));
        foreach (bool z in s) {

            a = (a + (z ? 90 : 270)) % 360;

            // new target
            switch (a) {
                case 90: x += distance; break;
                case 180: y += distance; break;
                case 270: x -= distance; break;
                default: y -= distance; break;
            }

            // move
            pc.Add(new Point(x, y));
        }

    }

    bool getNext() {
        cnt++;
        return (cnt & ((cnt & -cnt) << 1)) != 0;
    }

}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜