标题: [原创代码] Perl重绘inkscape生成的矢量图(.svg) [打印本页]
作者: 523066680 时间: 2016-11-8 21:14 标题: Perl重绘inkscape生成的矢量图(.svg)
没错,跳票已久的 “然而并没有什么卵用” 系列 (先自嘲一番,即使舆论出了偏差,也有心理准备)
首发 Perl+OpenGL 重绘inkscape生成的svg矢量图
当前主要是绘制路径,细节有待完善。multi.svg 由开源软件 inkscape 绘制并导出,你可以拖入浏览器中查看- =info
- Author: 523066680
- Date: 2016-11
- =cut
-
- use IO::Handle;
- use OpenGL qw/ :all /;
- use OpenGL::Config;
- use Time::HiRes 'sleep';
- use feature 'state';
-
- STDOUT->autoflush(1);
-
- open READ, "<:raw", "multi.svg";
- my @all;
- my $tl;
- for my $line (<READ>)
- {
- if ( $line=~/\s+d="(.*)"/ )
- {
- @all = split(" ", $1 );
- }
- }
-
- my @coords;
-
- for my $e (@all)
- {
- if ( $e =~/[a-zA-Z]/ )
- {
- $head = $e;
- next;
- }
- push @coords,
- {
- 'head' => $head,
- 'data' => [ split(",", $e) ],
- };
- }
-
- #相对坐标 叠加为绝对坐标
- my ($ox, $oy);
- for (my $i = 0; $i <= $#coords; $i++)
- {
- if ($coords[$i]->{head} eq 'c')
- {
- grep
- {
- $coords[ $i+$_ ]->{'data'}[0] += $ox;
- $coords[ $i+$_ ]->{'data'}[1] += $oy;
- } (0..2) ;
- $i += 2;
- }
- else
- {
-
- }
- #ox oy 始终是最后一点的坐标值
- ($ox, $oy) = ($coords[$i]->{'data'}[0], $coords[$i]->{'data'}[1]) ;
- }
-
- my ($xmin, $xmax, $ymin, $ymax) = (10000.0, -10000.0, 10000.0, -10000.0);
- for my $e (@coords)
- {
- printf("%.2f, %.2f\n", $e->{'data'}[0], $e->{'data'}[1]);
- $xmin = $e->{'data'}[0] if ($e->{'data'}[0] < $xmin);
- $xmax = $e->{'data'}[0] if ($e->{'data'}[0] > $xmax);
-
- $ymin = $e->{'data'}[1] if ($e->{'data'}[1] < $ymin);
- $ymax = $e->{'data'}[1] if ($e->{'data'}[1] > $ymax);
- }
- printf("%f %f %f %f\n", $xmin, $xmax, $ymin, $ymax);
-
- &Main();
-
- sub display
- {
- glClear(GL_COLOR_BUFFER_BIT);
- glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
-
- glPushMatrix();
-
- my $array;
- my @points;
-
- for (my $i = 0; $i <= $#coords; $i++)
- {
- if ($coords[$i]->{head} =~/C/i)
- {
- glColor4f(0.0,0.5,0.0,1.0);
- $array = OpenGL::Array->new( 3*4, GL_FLOAT);
- @points = (
- $coords[$i-1]->{'data'}[0], $coords[$i-1]->{'data'}[1], 0.0 ,
- $coords[$i+0]->{'data'}[0], $coords[$i+0]->{'data'}[1], 0.0 ,
- $coords[$i+1]->{'data'}[0], $coords[$i+1]->{'data'}[1], 0.0 ,
- $coords[$i+2]->{'data'}[0], $coords[$i+2]->{'data'}[1], 0.0 ,
- );
-
- $array->assign(0, @points);
-
- glMap1f_c(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, $array->ptr);
- glMapGrid1f(20, 0.0, 1.0);
- glEvalMesh1(GL_LINE, 0, 20);
- $i+=2;
- }
- elsif ($coords[$i]->{head} =~/Q/i)
- {
- glColor4f(0.0,0.5,0.0,1.0);
- $array = OpenGL::Array->new( 3*3, GL_FLOAT);
-
- @points = ( $coords[$i-1]->{'data'}[0], $coords[$i-1]->{'data'}[1], 0.0,
- $coords[$i+0]->{'data'}[0], $coords[$i+0]->{'data'}[1], 0.0 ,
- $coords[$i+1]->{'data'}[0], $coords[$i+1]->{'data'}[1], 0.0 ,
- );
-
- $array->assign(0, @points);
-
- glMap1f_c(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 3, $array->ptr);
- glMapGrid1f(20, 0.0, 1.0);
- glEvalMesh1(GL_LINE, 0, 20);
- $i += 1;
- }
- elsif ($coords[$i]->{head} =~/L/i)
- {
- glBegin(GL_LINES);
- glVertex3f( $coords[$i-1]->{'data'}[0], $coords[$i-1]->{'data'}[1], 0.0 );
- glVertex3f( $coords[$i]->{'data'}[0], $coords[$i]->{'data'}[1], 0.0 );
- glEnd();
- }
- elsif ($coords[$i]->{head} =~/M/i)
- {
- glBegin(GL_POINTS);
- glColor3f(1.0, 1.0, 1.0);
- glVertex3f( $coords[$i]->{'data'}[0], $coords[$i]->{'data'}[1], 0.0 );
- glEnd();
- }
- }
-
- glPopMatrix();
- glutSwapBuffers();
- }
-
- sub init
- {
- glClearColor(0.0, 0.0, 0.0, 1.0);
- glPointSize(2.0);
- glLineWidth(2.0);
- glEnable(GL_BLEND);
- glEnable(GL_POINT_SMOOTH);
- glEnable(GL_LINE_SMOOTH);
- glEnable(GL_MAP1_VERTEX_3);
- }
-
- sub idle
- {
- sleep 0.05;
- glutPostRedisplay();
- }
-
- sub Reshape
- {
- my $half = 1000;
- glViewport(0, 0, 500.0, 500.0);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- #glOrtho(-$half, $half, -$half, $half, 0.0, 200.0);
- glOrtho($xmin, $xmax, $ymin, $ymax, 0.0, 200.0);
- 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 );
- glutInitWindowSize(500, 500);
- glutInitWindowPosition(1,1);
- our $WinID = glutCreateWindow("title");
- &init();
- glutDisplayFunc(\&display);
- glutReshapeFunc(\&Reshape);
- glutKeyboardFunc(\&hitkey);
- glutIdleFunc(\&idle);
- glutMainLoop();
- }
-
-
- __END__
- 要使glMap1f_c 正常工作,需要借用OpenGL::Array 建立一个
- 仿C的指针
-
- my $array = OpenGL::Array->new( 3*4, GL_FLOAT);
- $array->assign(0, @points);
-
- glMap1f_c(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, $array->ptr);
- glEnable(GL_MAP1_VERTEX_3);
复制代码
IE浏览 VS 重绘
作者: happy886rr 时间: 2016-11-8 22:06
本帖最后由 happy886rr 于 2016-11-8 22:14 编辑
图形设计的非常有创意,兼具美学性、艺术性、极坐标性。放大400倍中间居然是个11角星。
花非花、雾非雾。
读君的代码就像在读诗。
作者: 523066680 时间: 2016-11-8 22:18
本帖最后由 523066680 于 2016-11-9 11:55 编辑
回复 2# happy886rr
(莫夸,要飞起来了……
(其实我的代码自带混淆,有待改善
作者: 523066680 时间: 2016-11-9 11:54
本帖最后由 523066680 于 2016-11-9 12:04 编辑
终于支持多个path了,刚开始代码纯粹靠堆起来的,有空再完善
已经玩坏了~
作者: codegay 时间: 2016-11-9 13:09
已经NB上天了。
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |