免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2399 | 回复: 8

Perl+OpenGL 重绘inkscape生成的svg矢量图 [复制链接]

论坛徽章:
12
子鼠
日期:2014-10-11 16:46:482016科比退役纪念章
日期:2018-03-16 10:24:0515-16赛季CBA联赛之山东
日期:2017-11-10 14:32:142016科比退役纪念章
日期:2017-09-02 15:42:4715-16赛季CBA联赛之佛山
日期:2017-08-28 17:11:5515-16赛季CBA联赛之浙江
日期:2017-08-24 16:55:1715-16赛季CBA联赛之青岛
日期:2017-08-17 19:55:2415-16赛季CBA联赛之天津
日期:2017-06-29 10:34:4315-16赛季CBA联赛之四川
日期:2017-05-16 16:38:55黑曼巴
日期:2016-07-19 15:03:112015亚冠之萨济拖拉机
日期:2015-05-22 11:38:5315-16赛季CBA联赛之北京
日期:2019-08-13 17:30:53
发表于 2016-11-09 16:29 |显示全部楼层
本帖最后由 523066680 于 2016-11-09 16:32 编辑





  1. =info
  2.     Author: 523066680
  3.       Date: 2016-11

  4.     V2.1 完善 q l m 的坐标叠加
  5.     v2.3 支持多个路径元素,但仍出现(文件夹图标)多余连线,原因:某些z标记被忽略
  6.         m 373.44757,313.00313
  7.         -12.8125,-12.8125
  8.         0,25.625
  9.         12.8125,-12.8125
  10.         z
  11.         m
  12.         10.33203,0.68359
  13.         -3.45703,3.4375
  14.     v2.4 解决2.3问题,窗口范围自适应

  15. =cut

  16. use IO::Handle;
  17. use OpenGL qw/ :all /;
  18. use OpenGL::Config;
  19. use Time::HiRes 'sleep';
  20. use feature 'state';
  21. STDOUT->autoflush(1);

  22. our $width  = 500;
  23. our $height = 500;

  24. open READ, "<:raw", "fonts3.svg" or die "$!";
  25. my @all;
  26. my $tl;
  27. for my $line (<READ>)
  28. {
  29.     if ( $line=~s/\s+d="(.*)"// )
  30.     {
  31.         push @all, split(" ",  $1);
  32.         push @all, ("w", "0,0") ;     #自定义边界 w
  33.     }
  34. }

  35. my @coords;

  36. for my $e (@all)
  37. {
  38.     if ( $e =~/[a-zA-Z]/ )
  39.     {
  40.         $head = $e;

  41.         #如果遇到单独z的边界,手动添加最后一次获取的坐标
  42.         if ($head =~/z/i)
  43.         {
  44.             push @coords,
  45.             {
  46.                 'head' => $head,
  47.                 'data' => $coords[-1]->{'data'},
  48.             };
  49.         }
  50.         next;
  51.     }
  52.     push @coords,
  53.         {
  54.             'head' => $head,
  55.             'data' => [ split(",", $e) ],
  56.         };
  57. }

  58. #相对坐标 叠加为绝对坐标
  59. my ($ox, $oy);
  60. for (my $i = 0; $i <= $#coords; $i++)
  61. {
  62.     if ($coords[$i]->{head} eq 'c')
  63.     {
  64.         grep
  65.         {
  66.             $coords[ $i+$_ ]->{'data'}[0] += $ox;
  67.             $coords[ $i+$_ ]->{'data'}[1] += $oy;
  68.         } (0..2) ;
  69.         $i += 2;
  70.     }
  71.     elsif ($coords[$i]->{head} eq 'q')
  72.     {
  73.         grep
  74.         {
  75.             $coords[ $i+$_ ]->{'data'}[0] += $ox;
  76.             $coords[ $i+$_ ]->{'data'}[1] += $oy;
  77.         } (0, 1) ;
  78.         $i += 1;
  79.     }
  80.     elsif ($coords[$i]->{head} eq 'l')
  81.     {
  82.         $coords[$i]->{'data'}[0] += $ox;
  83.         $coords[$i]->{'data'}[1] += $oy;
  84.     }
  85.     elsif ($coords[$i]->{head} eq 'm' and $i > 0)
  86.     {
  87.         $coords[$i]->{'data'}[0] += $ox ;
  88.         $coords[$i]->{'data'}[1] += $oy ;
  89.     }
  90.     elsif ($coords[$i]->{head} eq 'w')
  91.     {
  92.         $coords[$i]->{'data'}[0] = 0 ;
  93.         $coords[$i]->{'data'}[1] = 0 ;
  94.     }

  95.     #ox oy 始终是最后一点的坐标值
  96.     ($ox, $oy) = ($coords[$i]->{'data'}[0], $coords[$i]->{'data'}[1]) ;
  97. }

  98. my ($xmin, $xmax, $ymin, $ymax) = (10000.0, -10000.0, 10000.0, -10000.0);
  99. for my $e (@coords)
  100. {
  101.     next if ( $e->{head} eq 'w' );   #自定义标签不参与计算

  102.     printf("%s : %.2f, %.2f\n", $e->{'head'}, $e->{'data'}[0], $e->{'data'}[1]);
  103.     $xmin = $e->{'data'}[0] if ($e->{'data'}[0] < $xmin);
  104.     $xmax = $e->{'data'}[0] if ($e->{'data'}[0] > $xmax);

  105.     $ymin = $e->{'data'}[1] if ($e->{'data'}[1] < $ymin);
  106.     $ymax = $e->{'data'}[1] if ($e->{'data'}[1] > $ymax);
  107. }
  108. printf("xmin: %.2f, xmax: %.2f, ymin: %.2f, ymax: %.2f\n", $xmin, $xmax, $ymin, $ymax);

  109. &Main();

  110. sub drawPoint
  111. {
  112.     glBegin(GL_POINTS);
  113.         glVertex3f(  shift, shift, 1.0 );
  114.     glEnd();
  115. }

  116. sub drawLine
  117. {
  118.     glBegin(GL_LINES);
  119.         glVertex3f(  shift, shift, 1.0 );
  120.         glVertex3f(  shift, shift, 1.0 );
  121.     glEnd();
  122. }


  123. sub drawCurve
  124. {
  125.     my $n = shift;
  126.     my $array;
  127.     $array = OpenGL::Array->new( 3 * $n  , GL_FLOAT);
  128.     $array->assign(0, @_);

  129.     glMap1f_c(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, $n, $array->ptr);
  130.     glMapGrid1f(20, 0.0, 1.0);
  131.     glEvalMesh1(GL_LINE, 0, 20);
  132. }

  133. sub display
  134. {
  135.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  136.     glPushMatrix();
  137.     my $edge = 0;

  138.     for (my $i = 0; $i <= $#coords; $i++)
  139.     {
  140.         $coords[$i]->{'data'}[0] += rand() * 1.0 - 0.5 ;
  141.         $coords[$i]->{'data'}[1] += rand() * 1.0 - 0.5 ;
  142.         if ($coords[$i]->{head} =~/C/i)
  143.         {
  144.             glColor4f(1.0,0.5,0.0,1.0);
  145.             drawCurve( 4,
  146.                   @{$coords[$i-1]->{'data'}}, 0.0,
  147.                   @{$coords[$i+0]->{'data'}}, 0.0,
  148.                   @{$coords[$i+1]->{'data'}}, 0.0,
  149.                   @{$coords[$i+2]->{'data'}}, 0.0
  150.             );
  151.             $i+=2;
  152.             drawPoint( @{$coords[$i]->{'data'}} );
  153.         }
  154.         elsif ($coords[$i]->{head} =~/Q/i)
  155.         {
  156.             glColor4f(0.3, 0.7, 0.8, 1.0);
  157.             drawCurve( 3,
  158.                   @{$coords[$i-1]->{'data'}}, 0.0,
  159.                   @{$coords[$i+0]->{'data'}}, 0.0,
  160.                   @{$coords[$i+1]->{'data'}}, 0.0,
  161.             );
  162.             $i += 1;
  163.             drawPoint( @{$coords[$i]->{'data'}} );
  164.         }
  165.         elsif ($coords[$i]->{head} =~/L/i)
  166.         {
  167.             glColor3f(0.9, 0.6, 0.3);
  168.             drawLine( @{$coords[$i-1]->{'data'}},  @{$coords[$i]->{'data'}} );
  169.         }
  170.         elsif ($coords[$i]->{head} =~/M/i)
  171.         {
  172.             if ( $i > 0 and $coords[$i-1]->{head} =~/M/i )  #如果上一次也是m
  173.             {
  174.                 glColor3f(0.8, 0.3, 0.3);
  175.                 drawLine( @{$coords[$i-1]->{'data'}},  @{$coords[$i]->{'data'}} );

  176.                 # glColor3f(0.0, 0.0, 0.0);
  177.                 # drawPoint( @{$coords[$i]->{'data'}} );
  178.             }
  179.             else
  180.             {
  181.                 glColor3f(0.0, 0.0, 0.0);
  182.                 drawPoint( @{$coords[$i]->{'data'}} );
  183.             }
  184.         }
  185.     }

  186.     glPopMatrix();
  187.     glutSwapBuffers();
  188. }

  189. sub init
  190. {
  191.     glClearColor(1.0, 1.0, 0.9, 1.0);
  192.     glPointSize(4.0);
  193.     glLineWidth(2.0);
  194.     glEnable(GL_DEPTH_TEST);
  195.     glEnable(GL_POINT_SMOOTH);
  196.     glEnable(GL_LINE_SMOOTH);
  197.     glEnable(GL_MAP1_VERTEX_3);
  198. }

  199. sub idle
  200. {
  201.     sleep 0.01;
  202.     glutPostRedisplay();
  203. }

  204. sub Reshape
  205. {
  206.     our ($width, $height);
  207.     my $dtx = $xmax - $xmin;
  208.     my $dty = $ymax - $ymin;

  209.     if ( $dtx > $dty )
  210.     {
  211.         $dty *= $width / $dtx ;
  212.         $dtx = $width;
  213.     }
  214.     else
  215.     {
  216.         $dtx *= $height / $dty ;
  217.         $dty = $height;
  218.     }

  219.     glViewport(0, 0, $dtx, $dty );
  220.     glMatrixMode(GL_PROJECTION);
  221.     glLoadIdentity();
  222.     glOrtho($xmin, $xmax, $ymax, $ymin, 0.0, 200.0); #y轴颠倒
  223.     glMatrixMode(GL_MODELVIEW);
  224.     glLoadIdentity();
  225.     gluLookAt(0.0,0.0,100.0,0.0,0.0,0.0, 0.0,1.0,100.0);
  226. }

  227. sub hitkey
  228. {
  229.     my $keychar = lc(chr(shift));
  230.     if ($keychar eq 'q')
  231.     {
  232.         glutDestroyWindow($WinID);
  233.     }
  234. }

  235. sub Main
  236. {
  237.     glutInit();
  238.     glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE |GLUT_DEPTH |GLUT_MULTISAMPLE );
  239.     glutInitWindowSize(500, 500);
  240.     glutInitWindowPosition(1,1);
  241.     our $WinID = glutCreateWindow("title");
  242.     &init();
  243.     glutDisplayFunc(\&display);
  244.     glutReshapeFunc(\&Reshape);
  245.     glutKeyboardFunc(\&hitkey);
  246.     glutIdleFunc(\&idle);
  247.     glutMainLoop();
  248. }
复制代码

svg文件
drawSVG.zip (10.23 KB, 下载次数: 6)

论坛徽章:
12
子鼠
日期:2014-10-11 16:46:482016科比退役纪念章
日期:2018-03-16 10:24:0515-16赛季CBA联赛之山东
日期:2017-11-10 14:32:142016科比退役纪念章
日期:2017-09-02 15:42:4715-16赛季CBA联赛之佛山
日期:2017-08-28 17:11:5515-16赛季CBA联赛之浙江
日期:2017-08-24 16:55:1715-16赛季CBA联赛之青岛
日期:2017-08-17 19:55:2415-16赛季CBA联赛之天津
日期:2017-06-29 10:34:4315-16赛季CBA联赛之四川
日期:2017-05-16 16:38:55黑曼巴
日期:2016-07-19 15:03:112015亚冠之萨济拖拉机
日期:2015-05-22 11:38:5315-16赛季CBA联赛之北京
日期:2019-08-13 17:30:53
发表于 2016-11-10 11:25 |显示全部楼层
发帖审核要一天也真是……
如果到了一定等级是不是不用审核?

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
发表于 2016-11-10 21:30 |显示全部楼层
回复 2# 523066680

是的,多多分享你的经验,然后很快就没有审核了

论坛徽章:
12
子鼠
日期:2014-10-11 16:46:482016科比退役纪念章
日期:2018-03-16 10:24:0515-16赛季CBA联赛之山东
日期:2017-11-10 14:32:142016科比退役纪念章
日期:2017-09-02 15:42:4715-16赛季CBA联赛之佛山
日期:2017-08-28 17:11:5515-16赛季CBA联赛之浙江
日期:2017-08-24 16:55:1715-16赛季CBA联赛之青岛
日期:2017-08-17 19:55:2415-16赛季CBA联赛之天津
日期:2017-06-29 10:34:4315-16赛季CBA联赛之四川
日期:2017-05-16 16:38:55黑曼巴
日期:2016-07-19 15:03:112015亚冠之萨济拖拉机
日期:2015-05-22 11:38:5315-16赛季CBA联赛之北京
日期:2019-08-13 17:30:53
发表于 2016-11-10 22:15 |显示全部楼层
补充,需要安装opengl模块。

论坛徽章:
42
19周年集字徽章-周
日期:2019-10-14 14:35:31平安夜徽章
日期:2015-12-26 00:06:30数据库技术版块每日发帖之星
日期:2015-12-01 06:20:002015亚冠之首尔
日期:2015-11-04 22:25:43IT运维版块每日发帖之星
日期:2015-08-17 06:20:00寅虎
日期:2014-06-04 16:25:27狮子座
日期:2014-05-12 11:00:00辰龙
日期:2013-12-20 17:07:19射手座
日期:2013-10-24 21:01:23CU十二周年纪念徽章
日期:2013-10-24 15:41:34IT运维版块每日发帖之星
日期:2016-01-27 06:20:0015-16赛季CBA联赛之新疆
日期:2016-06-07 14:10:01
发表于 2016-11-11 15:42 |显示全部楼层
不太明白,是打开一个svg,然后转成动画?

论坛徽章:
12
子鼠
日期:2014-10-11 16:46:482016科比退役纪念章
日期:2018-03-16 10:24:0515-16赛季CBA联赛之山东
日期:2017-11-10 14:32:142016科比退役纪念章
日期:2017-09-02 15:42:4715-16赛季CBA联赛之佛山
日期:2017-08-28 17:11:5515-16赛季CBA联赛之浙江
日期:2017-08-24 16:55:1715-16赛季CBA联赛之青岛
日期:2017-08-17 19:55:2415-16赛季CBA联赛之天津
日期:2017-06-29 10:34:4315-16赛季CBA联赛之四川
日期:2017-05-16 16:38:55黑曼巴
日期:2016-07-19 15:03:112015亚冠之萨济拖拉机
日期:2015-05-22 11:38:5315-16赛季CBA联赛之北京
日期:2019-08-13 17:30:53
发表于 2016-11-11 18:33 |显示全部楼层
本帖最后由 523066680 于 2016-11-11 18:48 编辑

回复 5# laputa73

     准备下一步做动画或者小游戏。
     当前主要是提取、解读svg里面path标签下的线段、贝赛尔曲线坐标并绘制。
这一步完成了,后面设计时可以在inkscape,导出的svg作为素材。
而且这样一来,文字转为路径,保存到svg,也可以解读并绘制了。

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
发表于 2016-11-11 19:51 |显示全部楼层
回复 6# 523066680
我问下大神 perl 还能开发游戏呀? 是不是我看错了?

论坛徽章:
12
子鼠
日期:2014-10-11 16:46:482016科比退役纪念章
日期:2018-03-16 10:24:0515-16赛季CBA联赛之山东
日期:2017-11-10 14:32:142016科比退役纪念章
日期:2017-09-02 15:42:4715-16赛季CBA联赛之佛山
日期:2017-08-28 17:11:5515-16赛季CBA联赛之浙江
日期:2017-08-24 16:55:1715-16赛季CBA联赛之青岛
日期:2017-08-17 19:55:2415-16赛季CBA联赛之天津
日期:2017-06-29 10:34:4315-16赛季CBA联赛之四川
日期:2017-05-16 16:38:55黑曼巴
日期:2016-07-19 15:03:112015亚冠之萨济拖拉机
日期:2015-05-22 11:38:5315-16赛季CBA联赛之北京
日期:2019-08-13 17:30:53
发表于 2016-11-11 21:45 |显示全部楼层
回复 7# sunzhiguolu

其实看规模大小和怎么设计好吧,做个2D的碰撞试验之类,还是可以的。况且Perl效率也还行啊。

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
发表于 2016-11-11 22:00 |显示全部楼层
回复 8# 523066680
这可真是开眼了, 以前根本就没有想过 perl 可以搞游戏开发. 还以为这种事情都是高级语言干的事呢.

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP