我已将代码从javascript翻译成c#,可以通过http://fractal.qfox.nl/dragon.js
上的优秀演示找到我的翻译是为了在点击按钮时只产生一条龙,但我想我的版本中遗漏了一些东西 有关详细信息,请参阅维基百科文章:Dragon Curve。
不完整的龙分形输出: 的代码:
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;
break;
}
position[n] = position[n] + 1;
}
return r;
}
}
答案 0 :(得分:4)
我清理了代码,并尝试了解pattern
和position
数组应该如何生成正确的序列,但我无法弄明白。 pattern
数组中的最后一项例如从未使用过......
然而,有一种更简单的方法只使用计数器实现getNext
方法:
bool getNext() {
cnt++;
return (cnt & ((cnt & -cnt) << 1)) != 0;
}
我之前(约20年前)使用过该方法,我在dragon curve wikipedia page上找到了这个实现。
使用此getNext
实现的已清理代码如下所示:
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;
}
}