本帖最后由 523066680 于 2015-7-29 21:26 编辑

参考链接
Matrix67数学笔记 - 神奇的分形艺术(三):Sierpinski三角形
http://www.matrix67.com/blog/archives/280
wikipedia - Sierpinski triangle
http://en.wikipedia.org/wiki/Sierpinski_triangle | | | | | | | | | | | use IO::Handle; | | use OpenGL qw/ :all /; | | use OpenGL::Config; | | use Time::HiRes 'sleep'; | | use feature 'state'; | | | | our %T = ( | | 'A' => [-50.0, -30.0], | | 'B' => [50.0, -30.0], | | 'C' => [0.0, 50.0] | | ); | | | | STDOUT->autoflush(1); | | &Main(); | | | | sub func | | { | | my ($lv, $ref) = (shift, shift); | | if ($lv > 5) { return; } | | | | my $mAB = mid($ref->{'A'}, $ref->{'B'}); | | my $mAC = mid($ref->{'A'}, $ref->{'C'}); | | my $mBC = mid($ref->{'B'}, $ref->{'C'}); | | | | glBegin(GL_TRIANGLES); | | glColor4f( ($mAB->[0]+50.0)/100.0, ($mAB->[1] +50.0)/100.0, 0.6, 1.0); | | glVertex3f($mAB->[0], $mAB->[1], 0.0); | | glVertex3f($mAC->[0], $mAC->[1], 0.0); | | glVertex3f($mBC->[0], $mBC->[1], 0.0); | | glEnd(); | | | | my %T1 = ( | | 'A' => $ref->{'A'}, | | 'B' => $mAB, | | 'C' => $mAC | | ); | | func($lv+1, \%T1); | | | | my %T2 = ( | | 'A' => $ref->{'B'}, | | 'B' => $mAB, | | 'C' => $mBC | | ); | | func($lv+1, \%T2); | | | | my %T3 = ( | | 'A' => $ref->{'C'}, | | 'B' => $mAC, | | 'C' => $mBC | | ); | | func($lv+1, \%T3); | | | | } | | | | sub mid | | { | | my ($refA, $refB) = (shift, shift); | | my $x = ($refA->[0] + $refB->[0]) / 2; | | my $y = ($refA->[1] + $refB->[1]) / 2; | | return [$x, $y]; | | } | | | | sub display | | { | | our %T; | | | | glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA); | | glClear(GL_COLOR_BUFFER_BIT); | | | | glBegin(GL_TRIANGLES); | | glColor4f(1.0, 1.0, 1.0, 0.2); | | glVertex3f($T{'A'}->[0], $T{'A'}->[1], 0.0); | | glVertex3f($T{'B'}->[0], $T{'B'}->[1], 0.0); | | glVertex3f($T{'C'}->[0], $T{'C'}->[1], 0.0); | | glEnd(); | | &func(0, \%T); | | | | glutSwapBuffers(); | | | | } | | | | sub init | | { | | glClearColor(0.0, 0.0, 0.0, 1.0); | | glPointSize(3.0); | | glEnable(GL_BLEND); | | } | | | | sub idle | | { | | sleep 0.1; | | glutPostRedisplay(); | | } | | | | sub Reshape | | { | | glViewport(0.0,0.0,800.0,800.0); | | glMatrixMode(GL_PROJECTION); | | glLoadIdentity(); | | glOrtho(-100.0,100.0,-100.0,100.0,0.0,200.0); | | glScalef(1.8, 1.8, 1.8); | | glMatrixMode(GL_MODELVIEW); | | glLoadIdentity(); | | gluLookAt(0.0,0.0,100.0,0.0,0.0,0.0, 0.0,1.0,100.0); | | } | | | | sub hitkey | | { | | my $keychar = lc(chr(shift)); | | if ($keychar eq 'q') { | | glutDestroyWindow($WinID); | | } | | } | | | | sub Main | | { | | glutInit(); | | glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_MULTISAMPLE ); | | glutInitWindowSize(800, 800); | | glutInitWindowPosition(1,1); | | our $WinID = glutCreateWindow("Sierpinski"); | | &init(); | | glutDisplayFunc(\&display); | | glutReshapeFunc(\&Reshape); | | glutKeyboardFunc(\&hitkey); | | glutIdleFunc(\&idle); | | glutMainLoop(); | | }COPY |
|