- 论坛徽章:
- 12
|
本帖最后由 523066680 于 2016-11-09 16:32 编辑
- =info
- Author: 523066680
- Date: 2016-11
- V2.1 完善 q l m 的坐标叠加
- v2.3 支持多个路径元素,但仍出现(文件夹图标)多余连线,原因:某些z标记被忽略
- m 373.44757,313.00313
- -12.8125,-12.8125
- 0,25.625
- 12.8125,-12.8125
- z
- m
- 10.33203,0.68359
- -3.45703,3.4375
- v2.4 解决2.3问题,窗口范围自适应
- =cut
- use IO::Handle;
- use OpenGL qw/ :all /;
- use OpenGL::Config;
- use Time::HiRes 'sleep';
- use feature 'state';
- STDOUT->autoflush(1);
- our $width = 500;
- our $height = 500;
- open READ, "<:raw", "fonts3.svg" or die "$!";
- my @all;
- my $tl;
- for my $line (<READ>)
- {
- if ( $line=~s/\s+d="(.*)"// )
- {
- push @all, split(" ", $1);
- push @all, ("w", "0,0") ; #自定义边界 w
- }
- }
- my @coords;
- for my $e (@all)
- {
- if ( $e =~/[a-zA-Z]/ )
- {
- $head = $e;
- #如果遇到单独z的边界,手动添加最后一次获取的坐标
- if ($head =~/z/i)
- {
- push @coords,
- {
- 'head' => $head,
- 'data' => $coords[-1]->{'data'},
- };
- }
- 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;
- }
- elsif ($coords[$i]->{head} eq 'q')
- {
- grep
- {
- $coords[ $i+$_ ]->{'data'}[0] += $ox;
- $coords[ $i+$_ ]->{'data'}[1] += $oy;
- } (0, 1) ;
- $i += 1;
- }
- elsif ($coords[$i]->{head} eq 'l')
- {
- $coords[$i]->{'data'}[0] += $ox;
- $coords[$i]->{'data'}[1] += $oy;
- }
- elsif ($coords[$i]->{head} eq 'm' and $i > 0)
- {
- $coords[$i]->{'data'}[0] += $ox ;
- $coords[$i]->{'data'}[1] += $oy ;
- }
- elsif ($coords[$i]->{head} eq 'w')
- {
- $coords[$i]->{'data'}[0] = 0 ;
- $coords[$i]->{'data'}[1] = 0 ;
- }
- #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)
- {
- next if ( $e->{head} eq 'w' ); #自定义标签不参与计算
- printf("%s : %.2f, %.2f\n", $e->{'head'}, $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("xmin: %.2f, xmax: %.2f, ymin: %.2f, ymax: %.2f\n", $xmin, $xmax, $ymin, $ymax);
- &Main();
- sub drawPoint
- {
- glBegin(GL_POINTS);
- glVertex3f( shift, shift, 1.0 );
- glEnd();
- }
- sub drawLine
- {
- glBegin(GL_LINES);
- glVertex3f( shift, shift, 1.0 );
- glVertex3f( shift, shift, 1.0 );
- glEnd();
- }
- sub drawCurve
- {
- my $n = shift;
- my $array;
- $array = OpenGL::Array->new( 3 * $n , GL_FLOAT);
- $array->assign(0, @_);
- glMap1f_c(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, $n, $array->ptr);
- glMapGrid1f(20, 0.0, 1.0);
- glEvalMesh1(GL_LINE, 0, 20);
- }
- sub display
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glPushMatrix();
- my $edge = 0;
- for (my $i = 0; $i <= $#coords; $i++)
- {
- $coords[$i]->{'data'}[0] += rand() * 1.0 - 0.5 ;
- $coords[$i]->{'data'}[1] += rand() * 1.0 - 0.5 ;
- if ($coords[$i]->{head} =~/C/i)
- {
- glColor4f(1.0,0.5,0.0,1.0);
- drawCurve( 4,
- @{$coords[$i-1]->{'data'}}, 0.0,
- @{$coords[$i+0]->{'data'}}, 0.0,
- @{$coords[$i+1]->{'data'}}, 0.0,
- @{$coords[$i+2]->{'data'}}, 0.0
- );
- $i+=2;
- drawPoint( @{$coords[$i]->{'data'}} );
- }
- elsif ($coords[$i]->{head} =~/Q/i)
- {
- glColor4f(0.3, 0.7, 0.8, 1.0);
- drawCurve( 3,
- @{$coords[$i-1]->{'data'}}, 0.0,
- @{$coords[$i+0]->{'data'}}, 0.0,
- @{$coords[$i+1]->{'data'}}, 0.0,
- );
- $i += 1;
- drawPoint( @{$coords[$i]->{'data'}} );
- }
- elsif ($coords[$i]->{head} =~/L/i)
- {
- glColor3f(0.9, 0.6, 0.3);
- drawLine( @{$coords[$i-1]->{'data'}}, @{$coords[$i]->{'data'}} );
- }
- elsif ($coords[$i]->{head} =~/M/i)
- {
- if ( $i > 0 and $coords[$i-1]->{head} =~/M/i ) #如果上一次也是m
- {
- glColor3f(0.8, 0.3, 0.3);
- drawLine( @{$coords[$i-1]->{'data'}}, @{$coords[$i]->{'data'}} );
- # glColor3f(0.0, 0.0, 0.0);
- # drawPoint( @{$coords[$i]->{'data'}} );
- }
- else
- {
- glColor3f(0.0, 0.0, 0.0);
- drawPoint( @{$coords[$i]->{'data'}} );
- }
- }
- }
- glPopMatrix();
- glutSwapBuffers();
- }
- sub init
- {
- glClearColor(1.0, 1.0, 0.9, 1.0);
- glPointSize(4.0);
- glLineWidth(2.0);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_POINT_SMOOTH);
- glEnable(GL_LINE_SMOOTH);
- glEnable(GL_MAP1_VERTEX_3);
- }
- sub idle
- {
- sleep 0.01;
- glutPostRedisplay();
- }
- sub Reshape
- {
- our ($width, $height);
- my $dtx = $xmax - $xmin;
- my $dty = $ymax - $ymin;
- if ( $dtx > $dty )
- {
- $dty *= $width / $dtx ;
- $dtx = $width;
- }
- else
- {
- $dtx *= $height / $dty ;
- $dty = $height;
- }
- glViewport(0, 0, $dtx, $dty );
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho($xmin, $xmax, $ymax, $ymin, 0.0, 200.0); #y轴颠倒
- 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_DEPTH |GLUT_MULTISAMPLE );
- glutInitWindowSize(500, 500);
- glutInitWindowPosition(1,1);
- our $WinID = glutCreateWindow("title");
- &init();
- glutDisplayFunc(\&display);
- glutReshapeFunc(\&Reshape);
- glutKeyboardFunc(\&hitkey);
- glutIdleFunc(\&idle);
- glutMainLoop();
- }
复制代码
svg文件
drawSVG.zip
(10.23 KB, 下载次数: 6)
|
|