草庐IT

关于C#:Sierpinsky金字塔递归算法

codeneng 2023-03-28 原文

Sierpinsky pyramid recursive algorithm

我正在尝试实现一个谢尔宾斯基金字塔,它类似于谢尔宾斯基三角形,但是是 3D 的。
我有这个结构来包含有关金字塔的所有数据:

1
2
3
4
5
6
7
8
typedef struct
{
    GLfloat xUp;
    GLfloat yUp;
    GLfloat zUp;
    GLfloat base;
    GLfloat height;
}pyramid;

然后我写了一个计算三个子金字塔的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void findSubPyramids( pyramid pyr, pyramid subs[3])
{
    for(int i=0; i<3; i++)
    {
        subs[i].height=pyr.height/2.0;
        subs[i].base=pyr.base/2.0;
    }

    memcpy(subs,&pyr,3*sizeof(GLfloat));

    subs[1].yUp= pyr.yUp-pyr.height/2.0;
    subs[1].xUp= pyr.xUp+pyr.base/4.0;
    subs[1].zUp= pyr.zUp-pyr.base/4.0;

    subs[2].yUp= subs[1].yUp;
    subs[2].xUp= pyr.xUp-pyr.base/4.0;
    subs[2].zUp= subs[1].zUp;

}

但是这个算法实现是错误的:底部两个子金字塔的zUp坐标有问题:确实金字塔没有按我的意愿绘制:

但是,如果我使用 glOrtho 而不是 gluPerspective,则可以绘制金字塔。我知道我使用的 gluPerspective 和函数是正确的,但是算法是错误的。
这是我实现计算所有子金字塔的算法的地方:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void drawSierpinskyPyramid (pyramid pyr)
{
    assert(EQUAL(pyr.height, pyr.base));
    if(pyr.base > 4.0)
    {
        setRandomColor();
        pyramid subs[3];
        drawPyramid(pyr);
        findSubPyramids(pyr, subs);
        for(int i=0; i<3; i++)
        {
            drawSierpinskyPyramid(subs[i]);
        }
    }
}

我不明白出了什么问题。

  • 为什么 findSubPyramids() 不修改 subs[0]subs[] 不应该包含四个金字塔吗? drawPyramid() 实现在哪里?
  • 有 4 个子金字塔,但是已经绘制了一个金字塔,所以我需要继续绘制 3 个子金字塔。


试一试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// gcc -std=c99 main.c -lglut -lGL -lGLU

#include <GL/glut.h>
#include <math.h>
#include <stdlib.h>

typedef struct
{
    float x, y, z;
} Vec3f;

void glTriangle( Vec3f* v0, Vec3f* v1, Vec3f* v2 )
{
    glColor3ub( rand() % 255, rand() % 255, rand() % 255 );
    glVertex3fv( (GLfloat*)v0 );
    glVertex3fv( (GLfloat*)v1 );
    glVertex3fv( (GLfloat*)v2 );
}

// v0, v1, v2 = base, v3 = top
void glTetrahedron( Vec3f* v0, Vec3f* v1, Vec3f* v2, Vec3f* v3 )
{
    glTriangle( v0, v2, v1 );
    glTriangle( v0, v1, v3 );
    glTriangle( v1, v2, v3 );
    glTriangle( v2, v0, v3 );
}

Vec3f Lerp( Vec3f* v0, Vec3f* v1, float u )
{
    Vec3f ret = {
        v0->x + ( v1->x - v0->x ) * u,
        v0->y + ( v1->y - v0->y ) * u,
        v0->z + ( v1->z - v0->z ) * u,
    };
    return ret;
}

void glSierpinskiPyramid( Vec3f* v0, Vec3f* v1, Vec3f* v2, Vec3f* v3, unsigned int level )
{
    if( level == 0 )
    {
        glTetrahedron( v0, v1, v2, v3 );
        return;
    }

    // midpoints
    Vec3f m01 = Lerp( v0, v1, 0.5 );
    Vec3f m12 = Lerp( v1, v2, 0.5 );
    Vec3f m02 = Lerp( v0, v2, 0.5 );
    Vec3f m03 = Lerp( v0, v3, 0.5 );
    Vec3f m13 = Lerp( v1, v3, 0.5 );
    Vec3f m23 = Lerp( v2, v3, 0.5 );

    glSierpinskiPyramid( v0, &m01, &m02, &m03, level-1 );
    glSierpinskiPyramid( &m01, v1, &m12, &m13, level-1 );
    glSierpinskiPyramid( &m02, &m12, v2, &m23, level-1 );
    glSierpinskiPyramid( &m03, &m13, &m23, v3, level-1 );
}

void display()
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    double w = glutGet( GLUT_WINDOW_WIDTH );
    double h = glutGet( GLUT_WINDOW_HEIGHT );
    gluPerspective( 60, w / h, 0.1, 100 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    glTranslatef( 0, 0, -9 );

    srand(0);
    glPushMatrix();
    glScalef( 3, 3, 3 );

    static float angle = 0;
    angle += 1;
    glRotatef( angle/3, 0.2, 1, 0 );

    Vec3f v0 = { -1, -1 / sqrtf(3), -1 / sqrtf(6) };
    Vec3f v1 = {  1, -1 / sqrtf(3), -1 / sqrtf(6) };
    Vec3f v2 = {  0,  2 / sqrtf(3), -1 / sqrtf(6) };
    Vec3f v3 = {  0,             0,  3 / sqrtf(6) };
    glBegin( GL_TRIANGLES );
    glSierpinskiPyramid( &v0, &v1, &v2, &v3, 3 );
    glEnd();
    glPopMatrix();

    glutSwapBuffers();
}

void timer(int extra)
{
    glutPostRedisplay();
    glutTimerFunc(16, timer, 0);
}

int main( int argc, char **argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
    glutInitWindowSize( 640, 480 );
    glutCreateWindow("Sierpinski Pyramid" );
    glutDisplayFunc( display );
    glutTimerFunc(0, timer, 0);

    glEnable( GL_DEPTH_TEST );
    glEnable( GL_CULL_FACE );

    glutMainLoop();
    return 0;
}

  • 很棒的代码。所以我理解了这个问题,我必须画三角形,而不是金字塔,因为一个金字塔有 3*4 子三角形。

有关关于C#:Sierpinsky金字塔递归算法的更多相关文章

  1. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  2. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  3. 区块链之加解密算法&数字证书 - 2

    目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非

  4. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  5. ruby-on-rails - 关于 Ruby 的一般问题 - 2

    我在我的rails应用程序中安装了来自github.com的acts_as_versioned插件,但有一段代码我不完全理解,我希望有人能帮我解决这个问题class_eval我知道block内的方法(或任何它是什么)被定义为类内的实例方法,但我在插件的任何地方都找不到定义为常量的CLASS_METHODS,而且我也不确定是什么here,并且有问题的代码从lib/acts_as_versioned.rb的第199行开始。如果有人愿意告诉我这里的内幕,我将不胜感激。谢谢-C 最佳答案 这是一个异端。http://en.wikipedia

  6. ruby - 递归地将所有数字字符串转换为 Ruby 哈希中的整数 - 2

    我有一个随机大小的散列,它可能有类似"100"的值,我想将其转换为整数。我知道我可以使用value.to_iifvalue.to_i.to_s==value来做到这一点,但我不确定我将如何在我的散列中递归地做到这一点,考虑到一个值可以是一个字符串,或一个数组(哈希或字符串),或另一个哈希。 最佳答案 这是一个非常简单的递归实现(尽管必须同时处理数组和散列会增加一些技巧)。deffixnumifyobjifobj.respond_to?:to_i#IfwecancastittoaFixnum,doit.obj.to_ielsifobj

  7. Ruby:标准递归模式 - 2

    我经常迷上ruby​​的一件事是递归模式。例如,假设我有一个数组,它可能包含无限深度的数组作为元素。所以,例如:my_array=[1,[2,3,[4,5,[6,7]]]]我想创建一个方法,可以将数组展平为[1,2,3,4,5,6,7]。我知道.flatten可以完成这项工作,但这个问题是作为我经常遇到的递归问题的一个例子-因此我试图找到一个更可重用的解决方案。简而言之-我猜这种事情有一个标准模式,但我想不出任何特别优雅的东西。任何想法表示赞赏 最佳答案 递归是一种方法,它不依赖于语言。您在编写算法时要考虑两种情况:再次调用函数的情

  8. ruby - 为什么我用递归得到 "stack level too deep"? - 2

    我有这个ruby代码:defget_sumnreturn0ifn似乎正在为999之前的值工作。当我尝试9999时,它给了我这个:stackleveltoodeep(SystemStackError)所以,我添加了这个:RubyVM::InstructionSequence.compile_option={:tailcall_optimization=>true,:trace_instruction=>false}但什么也没发生。我的ruby版本是:ruby1.9.3p392(2013-02-22revision39386)[x86_64-darwin12.2.1]我还增加了机器的堆栈大

  9. ruby - 我怎样才能更好地了解/了解更多关于 Ruby 的知识? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我最近开始学习Ruby,这是我的第一门编程语言。我对语法感到满意,并且我已经完成了许多只教授相同基础知识的教程。我已经写了一些小程序(包括我自己的数组排序方法,在有人告诉我谷歌“冒泡排序”之前我认为它非常聪明),但我觉得我需要尝试更大更难的东西来理解更多关于Ruby.关于如何执行此操作的任何想法?

  10. ruby - 关于 Ruby 中 Dir[] 和 File.join() 的混淆 - 2

    我在Ruby中遇到了一个关于Dir[]和File.join()的简单程序,blobs_dir='/path/to/dir'Dir[File.join(blobs_dir,"**","*")].eachdo|file|FileUtils.rm_rf(file)ifFile.symlink?(file)我有两个困惑:首先,File.join(@blobs_dir,"**","*")中的第二个和第三个参数是什么意思?其次,Dir[]在Ruby中有什么用?我只知道它等价于Dir.glob(),但是,我对Dir.glob()确实不是很清楚。 最佳答案

随机推荐