[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[原创代码] Perl重绘inkscape生成的矢量图(.svg)

没错,跳票已久的 “然而并没有什么卵用” 系列 (先自嘲一番,即使舆论出了偏差,也有心理准备)

首发 Perl+OpenGL 重绘inkscape生成的svg矢量图

当前主要是绘制路径,细节有待完善。multi.svg 由开源软件 inkscape 绘制并导出,你可以拖入浏览器中查看
  1. =info
  2.     Author: 523066680
  3.       Date: 2016-11
  4. =cut
  5. use IO::Handle;
  6. use OpenGL qw/ :all /;
  7. use OpenGL::Config;
  8. use Time::HiRes 'sleep';
  9. use feature 'state';
  10. STDOUT->autoflush(1);
  11. open READ, "<:raw", "multi.svg";
  12. my @all;
  13. my $tl;
  14. for my $line (<READ>)
  15. {
  16.     if ( $line=~/\s+d="(.*)"/ )
  17.     {
  18.         @all = split(" ",  $1 );
  19.     }
  20. }
  21. my @coords;
  22. for my $e (@all)
  23. {
  24.     if ( $e =~/[a-zA-Z]/ )
  25.     {
  26.         $head = $e;
  27.         next;
  28.     }
  29.     push @coords,
  30.         {
  31.             'head' => $head,
  32.             'data' => [ split(",", $e) ],
  33.         };
  34. }
  35. #相对坐标 叠加为绝对坐标
  36. my ($ox, $oy);
  37. for (my $i = 0; $i <= $#coords; $i++)
  38. {
  39.     if ($coords[$i]->{head} eq 'c')
  40.     {
  41.         grep
  42.         {
  43.             $coords[ $i+$_ ]->{'data'}[0] += $ox;
  44.             $coords[ $i+$_ ]->{'data'}[1] += $oy;
  45.         } (0..2) ;
  46.         $i += 2;
  47.     }
  48.     else
  49.     {
  50.    
  51.     }
  52.     #ox oy 始终是最后一点的坐标值
  53.     ($ox, $oy) = ($coords[$i]->{'data'}[0], $coords[$i]->{'data'}[1]) ;
  54. }
  55. my ($xmin, $xmax, $ymin, $ymax) = (10000.0, -10000.0, 10000.0, -10000.0);
  56. for my $e (@coords)
  57. {
  58.     printf("%.2f, %.2f\n", $e->{'data'}[0], $e->{'data'}[1]);
  59.     $xmin = $e->{'data'}[0] if ($e->{'data'}[0] < $xmin);
  60.     $xmax = $e->{'data'}[0] if ($e->{'data'}[0] > $xmax);
  61.     $ymin = $e->{'data'}[1] if ($e->{'data'}[1] < $ymin);
  62.     $ymax = $e->{'data'}[1] if ($e->{'data'}[1] > $ymax);
  63. }
  64. printf("%f %f %f %f\n", $xmin, $xmax, $ymin, $ymax);
  65. &Main();
  66. sub display
  67. {
  68.     glClear(GL_COLOR_BUFFER_BIT);
  69.     glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
  70.     glPushMatrix();
  71.     my $array;
  72.     my @points;
  73.     for (my $i = 0; $i <= $#coords; $i++)
  74.     {
  75.         if ($coords[$i]->{head} =~/C/i)
  76.         {
  77.             glColor4f(0.0,0.5,0.0,1.0);
  78.             $array = OpenGL::Array->new( 3*4, GL_FLOAT);
  79.             @points = (
  80.                         $coords[$i-1]->{'data'}[0], $coords[$i-1]->{'data'}[1], 0.0 ,
  81.                         $coords[$i+0]->{'data'}[0], $coords[$i+0]->{'data'}[1], 0.0 ,
  82.                         $coords[$i+1]->{'data'}[0], $coords[$i+1]->{'data'}[1], 0.0 ,
  83.                         $coords[$i+2]->{'data'}[0], $coords[$i+2]->{'data'}[1], 0.0 ,
  84.                         );
  85.             $array->assign(0, @points);
  86.             glMap1f_c(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, $array->ptr);
  87.             glMapGrid1f(20, 0.0, 1.0);
  88.             glEvalMesh1(GL_LINE, 0, 20);
  89.             $i+=2;
  90.         }
  91.         elsif ($coords[$i]->{head} =~/Q/i)
  92.         {
  93.             glColor4f(0.0,0.5,0.0,1.0);
  94.             $array = OpenGL::Array->new( 3*3, GL_FLOAT);
  95.             @points = ( $coords[$i-1]->{'data'}[0], $coords[$i-1]->{'data'}[1], 0.0,
  96.                         $coords[$i+0]->{'data'}[0], $coords[$i+0]->{'data'}[1], 0.0 ,
  97.                         $coords[$i+1]->{'data'}[0], $coords[$i+1]->{'data'}[1], 0.0 ,
  98.                         );
  99.             $array->assign(0, @points);
  100.             glMap1f_c(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 3, $array->ptr);
  101.             glMapGrid1f(20, 0.0, 1.0);
  102.             glEvalMesh1(GL_LINE, 0, 20);
  103.             $i += 1;
  104.         }
  105.         elsif ($coords[$i]->{head} =~/L/i)
  106.         {
  107.             glBegin(GL_LINES);
  108.                 glVertex3f(  $coords[$i-1]->{'data'}[0], $coords[$i-1]->{'data'}[1], 0.0 );
  109.                 glVertex3f(  $coords[$i]->{'data'}[0], $coords[$i]->{'data'}[1], 0.0 );
  110.             glEnd();
  111.         }
  112.         elsif ($coords[$i]->{head} =~/M/i)
  113.         {
  114.             glBegin(GL_POINTS);
  115.                 glColor3f(1.0, 1.0, 1.0);
  116.                 glVertex3f(  $coords[$i]->{'data'}[0], $coords[$i]->{'data'}[1], 0.0 );
  117.             glEnd();
  118.         }
  119.     }
  120.     glPopMatrix();
  121.     glutSwapBuffers();
  122. }
  123. sub init
  124. {
  125.     glClearColor(0.0, 0.0, 0.0, 1.0);
  126.     glPointSize(2.0);
  127.     glLineWidth(2.0);
  128.     glEnable(GL_BLEND);
  129.     glEnable(GL_POINT_SMOOTH);
  130.     glEnable(GL_LINE_SMOOTH);
  131.     glEnable(GL_MAP1_VERTEX_3);
  132. }
  133. sub idle
  134. {
  135.     sleep 0.05;
  136.     glutPostRedisplay();
  137. }
  138. sub Reshape
  139. {
  140.     my $half = 1000;
  141.     glViewport(0, 0, 500.0, 500.0);
  142.     glMatrixMode(GL_PROJECTION);
  143.     glLoadIdentity();
  144.     #glOrtho(-$half, $half, -$half, $half, 0.0, 200.0);
  145.     glOrtho($xmin, $xmax, $ymin, $ymax, 0.0, 200.0);
  146.     glMatrixMode(GL_MODELVIEW);
  147.     glLoadIdentity();
  148.     gluLookAt(0.0,0.0,100.0,0.0,0.0,0.0, 0.0,1.0,100.0);
  149. }
  150. sub hitkey
  151. {
  152.     my $keychar = lc(chr(shift));
  153.     if ($keychar eq 'q')
  154.     {
  155.         glutDestroyWindow($WinID);
  156.     }
  157. }
  158. sub Main
  159. {
  160.     glutInit();
  161.     glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE );
  162.     glutInitWindowSize(500, 500);
  163.     glutInitWindowPosition(1,1);
  164.     our $WinID = glutCreateWindow("title");
  165.     &init();
  166.     glutDisplayFunc(\&display);
  167.     glutReshapeFunc(\&Reshape);
  168.     glutKeyboardFunc(\&hitkey);
  169.     glutIdleFunc(\&idle);
  170.     glutMainLoop();
  171. }
  172. __END__
  173. 要使glMap1f_c 正常工作,需要借用OpenGL::Array 建立一个
  174. 仿C的指针
  175.     my $array = OpenGL::Array->new( 3*4, GL_FLOAT);
  176.     $array->assign(0, @points);
  177.     glMap1f_c(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, $array->ptr);
  178.     glEnable(GL_MAP1_VERTEX_3);
复制代码
IE浏览  VS 重绘
1

评分人数

本帖最后由 happy886rr 于 2016-11-8 22:14 编辑

图形设计的非常有创意,兼具美学性、艺术性、极坐标性。放大400倍中间居然是个11角星。
花非花、雾非雾。
读君的代码就像在读诗。

TOP

本帖最后由 523066680 于 2016-11-9 11:55 编辑

回复 2# happy886rr


    (莫夸,要飞起来了……
    (其实我的代码自带混淆,有待改善

TOP

本帖最后由 523066680 于 2016-11-9 12:04 编辑

终于支持多个path了,刚开始代码纯粹靠堆起来的,有空再完善

已经玩坏了~

TOP



已经NB上天了。
去学去写去用才有进步。安装python3代码存为xx.py 双击运行或右键用IDLE打开按F5运行

TOP

返回列表