Python to Plot Graphics and Output Vector XY Pairs -
i need draw vector graphics, new me.
looking recommendations python modules can plot vector shapes , output them series of xy moves. shapes circles , lines , other simple shapes, have algorithmic modifiers thicken, wiggle, or "grunge up" lines.
i saw few of plot libraries (mathgl, matplotlib, pyplot), seem create graphics. ultimately, want break down output series of xy instructions consisting of lot of little straight lines.
(i using python output instructions digital-to-analog converter controlling xy movements of laser.)
please forgive blundering of question. i'll update question able formulate better.
edit: on other hand, maybe simple move handy maths maybe pymodule overkill. open suggestions cutting curves lines.
edit2: in end, ended doing own calculations, using pyglet vector graphic output.
i ended using pyglet vector graphic output, , doing own calculations drawing circles , lines of cubicspline code nyu.
#!/usr/bin/env python # core modules itertools import chain # installed modules import pyglet import numpy # local modules import config # constants curve_segs = config.curve_segments # number of line segs in curve # bezier curves courtesy of nyu def fac( k ): ''' returns k!. ''' if k == 0: return 1 else: return reduce(lambda i,j : i*j, range(1,k+1)) def binom( n, k ): ''' returns n choose k. ''' if k < 0 or k > n: return 0 return fac( n ) / ( fac( k ) * fac( n - k ) ) def b( p, t ): ''' evaluates bezier curve of degree len(p) - 1, using control points 'p', @ parameter value 't' in [0,1]. ''' n = len( p ) - 1 assert n > 0 numpy import zeros result = zeros( len( p[0] ) ) in xrange( n + 1 ): result += binom( n, ) * p[i] * (1 - t)**(n-i) * t**i return result def b_n( p, n, t ): ''' evaluates bezier curve of degree 'n', using control points 'p', @ parameter value 't' in [0,1]. ''' ## clamp t range [0,1] t = min( 1., max( 0., t ) ) num_segments = 1 + (len( p ) - (n+1) + n-1) // n assert num_segments > 0 math import floor segment_offset = min( int( floor( t * num_segments ) ), num_segments-1 ) p_offset = segment_offset * n return b( p[ p_offset : p_offset + n+1 ], ( t - segment_offset/float(num_segments) ) * num_segments ) def bezier_curve( p ): ''' returns function object can called parameters between 0 , 1 evaluate bezier curve control points 'p' , degree len(p)-1. ''' return lambda t: b( p, t ) def bezier_curve_n( p, n ): ''' returns function object can called parameters between 0 , 1 evaluate bezier curve strip control points 'p' , degree n. ''' return lambda t: b_n( p, n, t ) def cubicspline(p0, p1, p2, p3, nsteps): """returns list of line segments , index make full curve. cubics defined start point (p0) , end point (p3) , control points (p1 & p2) , parameter t goes 0.0 1.0. """ points = numpy.array([p0, p1, p2, p3]) bez = bezier.bezier_curve( points ) linesegments = [] val in numpy.linspace( 0, 1, nsteps ): #print '%s: %s' % (val, bez( val )) # definition of spline means parameter t goes # 0.0 1.0 (x,y) = bez(val) linesegments.append((int(x),int(y))) #linesegments.append(p2) cubicindex = [0] + [int(x * 0.5) x in range(2, (nsteps-1)*2)] + [nsteps-1] #print "linesegments = ",linesegments #print "cubicindex = ",cubicindex return (linesegments,cubicindex) # graphic primatives class graphicobject(object): """basic graphic object primative""" def __init__(self, field, points, index, color): """graphic object constructor. args: arcpoints - list of points define graphic object arcindex - list of indicies arcpoints color - list of colors of each arc """ self.m_field = field self.m_arcpoints = points self.m_arcindex = index self.m_color = color # each arc broken down list of points , indecies # these gathered lists of lists # todo: possibly these melded single dim lists self.m_points = [] self.m_index = [] class circle(graphicobject): """define circle object.""" def __init__(self, field, p, r, color,solid=false): """circle constructor. args: p - center point r - radius of circle c - color """ self.m_center = p self.m_radius = r self.m_solid = solid k = 0.5522847498307935 # 4/3 (sqrt(2)-1) kr = int(r*k) (x,y)=p arcpoints=[(x+r,y),(x+r,y+kr), (x+kr,y+r), (x,y+r), (x-kr,y+r), (x-r,y+kr), (x-r,y), (x-r,y-kr), (x-kr,y-r), (x,y-r), (x+kr,y-r), (x+r,y-kr)] arcindex=[(0, 1, 2, 3), (3, 4, 5, 6), (6, 7, 8, 9), (9, 10, 11, 0)] graphicobject.__init__(self,field,arcpoints,arcindex,color) def render(self): # e.g., self.m_arcpoints = [(10,5),(15,5),(15,10),(15,15),(10,15),(5,15),(5,10)] # e.g., self.m_arcindex = [(0,1,2,3),(3,4,5,6)] in range(len(self.m_arcindex)): # e.g., self.m_arcindex[i] = (0,1,2) p0 = self.m_arcpoints[self.m_arcindex[i][0]] p1 = self.m_arcpoints[self.m_arcindex[i][1]] p2 = self.m_arcpoints[self.m_arcindex[i][2]] p3 = self.m_arcpoints[self.m_arcindex[i][3]] (points,index) = cubicspline(p0,p1,p2,p3,curve_segs) if self.m_solid: points.append(self.m_center) nxlast_pt = len(points)-2 last_pt = len(points)-1 xtra_index = [nxlast_pt,last_pt,last_pt,0] index = index + xtra_index self.m_points.append(points) self.m_index.append(index) def draw(self): in range(len(self.m_index)): points = self.m_points[i] index = self.m_index[i] pyglet.gl.glcolor3f(self.m_color[0],self.m_color[1],self.m_color[2]) if not self.m_solid: pyglet.graphics.draw_indexed(len(points), pyglet.gl.gl_lines, index, ('v2i',self.m_field.scale2out(tuple(chain(*points)))), ) else: pyglet.graphics.draw_indexed(len(points), pyglet.gl.gl_polygon, index, ('v2i',self.m_field.scale2out(tuple(chain(*points)))), )
this not runnable code because missing constants , classes, might theory if struggling it.
each graphicobject, including circles , lines, composed of arcs, each 4 control points. there made of list of points , index points.
similarly, different, pyglet wanted straight line segments consisting of 2 points, index points. there bit of translation involved.
edit: earlier, had implemented bezier quadratic splines (essentially parabolas) made funny non-circular circles. code above uses bezier cubic splines render true circles.
Comments
Post a Comment