Perl+OpenGL 重繪inkscape生成的svg矢量圖
還不夠完善,先挖個坑,後面慢慢填php
Code: [全選] [展開/收縮] [Download] (Untitled.pl)dom
=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} eq 'C') { 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} eq 'c') { 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} eq 'L') { 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);
請將一下內容保存到multi.svg,保存後能夠拖入IE或者火狐中瀏覽。ide
Code: [全選] [展開/收縮] [Download] (multi.svg)svg
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="210mm" height="297mm" viewBox="0 0 744.09448819 1052.3622047" id="svg2" version="1.1" inkscape:version="0.91 r13725" sodipodi:docname="penta.svg"> <defs id="defs4" /> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1.4" inkscape:cx="402.20655" inkscape:cy="647.84062" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" inkscape:window-width="1440" inkscape:window-height="837" inkscape:window-x="-4" inkscape:window-y="120" inkscape:window-maximized="1" /> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title></dc:title> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1"> <path sodipodi:type="star" style="fill-rule:evenodd" id="path4140" sodipodi:sides="11" sodipodi:cx="421.86606" sodipodi:cy="388.68654" sodipodi:r1="219.29707" sodipodi:r2="63.376858" sodipodi:arg1="0.029801473" sodipodi:arg2="-2.8262334" inkscape:flatsided="false" inkscape:rounded="-0.07" inkscape:randomized="0" d="m 641.06576,395.22096 c -0.58462,19.63861 -285.54568,-7.5131 -279.45113,-26.19125 6.09452,-18.67807 252.23038,127.45733 241.12118,143.66224 C 591.62657,528.89693 366.58139,351.99388 381.80662,339.57579 397.03179,327.15774 525.08769,583.16575 506.981,590.7921 488.87423,598.41849 395.1952,327.92957 414.7172,325.71418 c 19.52193,-2.21538 -11.15897,282.38451 -30.51441,279.01099 -19.35551,-3.37353 48.07402,-281.57 65.6947,-272.87931 17.62062,8.69065 -162.05612,231.52397 -176.51508,218.22165 -14.45903,-13.30238 192.67067,-210.88099 202.79559,-194.04345 10.12488,16.83746 -261.50159,107.1562 -266.47347,88.14847 -4.9719,-19.00782 276.09575,-73.23875 275.51032,-53.60016 -0.58543,19.6385 -277.92215,-51.2329 -271.82841,-69.91123 6.09378,-18.6784 271.86238,87.65628 260.75247,103.8608 -11.10987,16.20446 -206.1044,-193.35592 -190.87975,-205.77459 15.22471,-12.41873 181.31462,220.72105 163.20754,228.34669 -18.107,7.6256 -68.84995,-274.0898 -49.32811,-276.30599 19.52191,-2.2162 33.20075,283.70845 13.84538,280.33412 -19.3553,-3.37432 90.26387,-267.80211 107.88484,-259.11218 17.62105,8.68996 -125.45412,256.62042 -139.91259,243.31744 -14.45842,-13.30292 220.71955,-176.48913 230.84513,-159.65209 10.12562,16.83712 -244.2782,148.05723 -249.24931,129.04921 -4.97109,-19.00794 281.09833,-29.14211 280.51372,-9.50359 z" /> </g> </svg>