def effect(self): scale = self.unittouu('1px') # convert to document units so = self.options rows = so.ROWS cols = so.COLS if (so.SYMBOL != '' and (so.SYMBOL in symbols)): rows = symbols[so.SYMBOL][0] cols = symbols[so.SYMBOL][1] if so.TEXT == '': #abort if converting blank text inkex.errormsg(_('Please enter an input string')) else: #INKSCAPE GROUP TO CONTAIN EVERYTHING centre = tuple(computePointInNode(list(self.view_center), self.current_layer)) #Put in in the centre of the current view grp_transform = 'translate' + str( centre ) + ' scale(%f)' % scale grp_name = 'DataMatrix' grp_attribs = {inkex.addNS('label','inkscape'):grp_name, 'transform':grp_transform } grp = inkex.etree.SubElement(self.current_layer, 'g', grp_attribs)#the group to put everything in #GENERATE THE DATAMATRIX encoded = encode( so.TEXT, (rows, cols) ) #get the pattern of squares render_data_matrix( encoded, so.SIZE, cols*so.SIZE*1.5, grp ) # generate the SVG elements
def effect(self): scale = self.unittouu('1px') # convert to document units so = self.options if so.TEXT == '': #abort if converting blank text inkex.errormsg(_('Please enter an input text')) else: #INKSCAPE GROUP TO CONTAIN EVERYTHING so.TEXT = unicode(so.TEXT, so.input_encode) centre = tuple( computePointInNode(list(self.view_center), self.current_layer) ) #Put in in the centre of the current view grp_transform = 'translate' + str(centre) + ' scale(%f)' % scale grp_name = 'QR Code: ' + so.TEXT grp_attribs = { inkex.addNS('label', 'inkscape'): grp_name, 'transform': grp_transform } grp = inkex.etree.SubElement( self.current_layer, 'g', grp_attribs) #the group to put everything in #GENERATE THE QRCODE qr = QRCode(int(so.TYPENUMBER), int(so.CORRECTIONLEVEL)) qr.addData(so.TEXT) qr.make() qr.makeSVG(grp, so.MODULESIZE)
def effect(self): """ This is the main entry point for the extension. """ # compute center of the view center = tuple( computePointInNode(list(self.view_center), self.current_layer)) # create the group that holds all the elements container = self.current_layer if self.options.wrap_in_group: group_attributes = { inkex.addNS('label', 'inkscape'): 'BouwkampSquares', 'transform': 'translate' + str(center) } group = inkex.etree.SubElement(self.current_layer, 'g', group_attributes) container = group # parse the bouwkamp code string as a list bouwkamp_code = self.parse_bouwkamp_code_from_string( self.options.bouwkamp_code) # show an error message and exit if the bouwkamp code is invalid try: self.exception_on_invalid_bouwkamp_code(bouwkamp_code) except ValueError as exception: inkex.errormsg(_(exception.message)) return # draw the bouwkamp code self.draw_bouwkamp_code(container, center, bouwkamp_code)
def effect(self): scale = self.unittouu("1px") # convert to document units so = self.options if so.TEXT == "": # abort if converting blank text inkex.errormsg(_("Please enter an input text")) else: # INKSCAPE GROUP TO CONTAIN EVERYTHING so.TEXT = unicode(so.TEXT, so.input_encode) centre = tuple( computePointInNode(list(self.view_center), self.current_layer) ) # Put in in the centre of the current view grp_transform = "translate" + str(centre) + " scale(%f)" % scale grp_name = "QR Code: " + so.TEXT grp_attribs = {inkex.addNS("label", "inkscape"): grp_name, "transform": grp_transform} grp = inkex.etree.SubElement(self.current_layer, "g", grp_attribs) # the group to put everything in # GENERATE THE QRCODE qr = QRCode(int(so.TYPENUMBER), int(so.CORRECTIONLEVEL)) qr.addData(so.TEXT) qr.make() qr.makeSVG(grp, so.MODULESIZE)
def effect(self): view_center = computePointInNode(list(self.view_center), self.current_layer) for id, node in self.selected.iteritems(): rotation = -1 if self.options.rotation == True: rotation = 1 whirl = self.options.whirl / 1000 if node.tag == inkex.addNS('path', 'svg'): d = node.get('d') p = cubicsuperpath.parsePath(d) for sub in p: for csp in sub: for point in csp: point[0] -= view_center[0] point[1] -= view_center[1] dist = math.sqrt((point[0]**2) + (point[1]**2)) if dist != 0: a = rotation * dist * whirl theta = math.atan2(point[1], point[0]) + a point[0] = (dist * math.cos(theta)) point[1] = (dist * math.sin(theta)) point[0] += view_center[0] point[1] += view_center[1] node.set('d', cubicsuperpath.formatPath(p))
def __compose_path(self, string): self.turtle.pu() self.turtle.setpos( computePointInNode(list(self.view_center), self.current_layer)) self.turtle.pd() for c in string: if c in 'ABCDEF': self.turtle.pd() self.turtle.fd(self.options.step * (random.normalvariate( 1.0, 0.01 * self.options.randomizestep))) elif c in 'GHIJKL': self.turtle.pu() self.turtle.fd(self.options.step * (random.normalvariate( 1.0, 0.01 * self.options.randomizestep))) elif c == '+': self.turtle.lt(self.options.langle * (random.normalvariate( 1.0, 0.01 * self.options.randomizeangle))) elif c == '-': self.turtle.rt(self.options.rangle * (random.normalvariate( 1.0, 0.01 * self.options.randomizeangle))) elif c == '|': self.turtle.lt(180) elif c == '[': self.stack.append( [self.turtle.getpos(), self.turtle.getheading()]) elif c == ']': self.turtle.pu() pos, heading = self.stack.pop() self.turtle.setpos(pos) self.turtle.setheading(heading)
def computePtInNode(vc, layer): if(CommonDefs.inkVer == 1.0): # ~ return (-Transform(layer.transform * mat)).apply_to_point(vc) return (-layer.transform).apply_to_point(vc) else: if(oldVersion): return list(vc) else: return computePointInNode(list(vc), layer)
def effect(self): scale = self.unittouu('1px') # convert to document units so = self.options so.TEXT = 'BEGIN:VCARD\nVERSION:3.0\nN:' so.TEXT_SURNAME = so.TEXT_SURNAME.decode(so.input_decode) so.TEXT = so.TEXT + so.TEXT_SURNAME so.TEXT_NAME = so.TEXT_NAME.decode(so.input_decode) so.TEXT = so.TEXT + ';' + so.TEXT_NAME + ';' so.TEXT_MNAME = so.TEXT_MNAME.decode(so.input_decode) so.TEXT = so.TEXT + so.TEXT_MNAME + '\nORG:' so.TEXT_ORGANIZATION = so.TEXT_ORGANIZATION.decode(so.input_decode) so.TEXT = so.TEXT + so.TEXT_ORGANIZATION + '\nTITLE:' so.TEXT_TITLE = so.TEXT_TITLE.decode(so.input_decode) so.TEXT = so.TEXT + so.TEXT_TITLE + '\nTEL:' so.TEXT_PHONE = so.TEXT_PHONE.decode(so.input_decode) so.TEXT = so.TEXT + so.TEXT_PHONE + '\nEMAIL:' so.TEXT_EMAIL = so.TEXT_EMAIL.decode(so.input_decode) so.TEXT = so.TEXT + so.TEXT_EMAIL + '\nURL:' so.TEXT_SITE = so.TEXT_SITE.decode(so.input_decode) so.TEXT = so.TEXT + so.TEXT_SITE + '\nEND:VCARD' so.TEXT = so.TEXT.encode(so.input_encode) #Anto #print(so.TEXT_SITE) if so.TEXT == '': #abort if converting blank text inkex.errormsg(_('Please enter an input text')) else: #INKSCAPE GROUP TO CONTAIN EVERYTHING #so.TEXT = ':'.join(x.encode('hex') for x in so.TEXT_SURNAME) # # inkex.errormsg(_(so.TEXT)) centre = tuple( computePointInNode(list(self.view_center), self.current_layer) ) #Put in in the centre of the current view grp_transform = 'translate' + str(centre) + ' scale(%f)' % scale grp_name = 'QR Code' grp_attribs = { inkex.addNS('label', 'inkscape'): grp_name, 'transform': grp_transform } grp = inkex.etree.SubElement( self.current_layer, 'g', grp_attribs) #the group to put everything in #GENERATE THE QRCODE qr = QRCode(int(so.TYPENUMBER), int(so.CORRECTIONLEVEL)) qr.addData(so.TEXT) qr.make() qr.makeSVG(grp, so.MODULESIZE)
def effect(self): opts = self.options version, error = opts.version, opts.error if version.upper() == 'M1' and error: error = None if version == '-': version = None micro = None if opts.micro == 'true' else False boost_error = opts.boost_error == 'true' want_background = opts.background == 'true' qr = encoder.encode(opts.data, version=version, error=error, micro=micro, boost_error=boost_error) border = utils.get_default_border_size(qr.version) # Create path data x, y = border, border + .5 # .5 == stroke-width / 2 line_iter = utils.matrix_to_lines(qr.matrix, x, y) # 1st coord is absolute (x1, y1), (x2, y2) = next(line_iter) coord = ['M{0} {1}h{2}'.format(x1, y1, x2 - x1)] append_coord = coord.append x, y = x2, y2 for (x1, y1), (x2, y2) in line_iter: append_coord('m{0} {1}h{2}'.format(x1 - x, int(y1 - y), x2 - x1)) x, y = x2, y2 path_data = ''.join(coord) centre = tuple( computePointInNode(list(self.view_center), self.current_layer)) grp_transform = 'translate' + str(centre) if opts.scale != 1: grp_transform += ' scale(%f)' % opts.scale grp = inkex.etree.SubElement(self.current_layer, inkex.addNS('g', 'svg'), transform=grp_transform) if want_background: width, height = utils.get_symbol_size(qr.version, border=border) inkex.etree.SubElement(grp, inkex.addNS('rect', 'svg'), width=str(width), height=str(height), fill='#FFF') inkex.etree.SubElement(grp, inkex.addNS('path', 'svg'), d=path_data, stroke='#000')
def effect(self): (pos_x, pos_y) = computePointInNode( list(self.view_center), self.current_layer) barcode = getBarcode(self.options.type, text=self.options.text, height=self.options.height, document=self.document, x=pos_x, y=pos_y, scale=self.unittouu('1px'), ).generate() if barcode is not None: self.current_layer.append(barcode) else: sys.stderr.write("No barcode was generated\n")
def effect(self): self.options.size = self.unittouu(str(self.options.size) + 'px') self.options.minimum = self.unittouu(str(self.options.minimum) + 'px') s = {'stroke-linejoin': 'miter', 'stroke-width': str(self.unittouu('1px')), 'stroke-opacity': '1.0', 'fill-opacity': '1.0', 'stroke': '#000000', 'stroke-linecap': 'butt', 'fill': 'none'} t = pturtle.pTurtle() t.pu() t.setpos(computePointInNode(list(self.view_center), self.current_layer)) t.pd() rtree(t, self.options.size, self.options.minimum, self.options.pentoggle) attribs = {'d':t.getPath(),'style':simplestyle.formatStyle(s)} inkex.etree.SubElement(self.current_layer, inkex.addNS('path','svg'), attribs)
def effect(self): # Embed text in group to make manipulation easier: g_attribs = {inkex.addNS('label', 'inkscape'): 'Hershey Text'} g = inkex.etree.SubElement(self.current_layer, 'g', g_attribs) scale = self.unittouu('1px') # convert to document units font = eval('hersheydata.' + str(self.options.fontface)) clearfont = hersheydata.futural #Baseline: modernized roman simplex from JHF distribution. w = 0 #Initial spacing offset spacing = 3 # spacing between letters if self.options.action == "render": #evaluate text string letterVals = [ord(q) - 32 for q in self.options.text] for q in letterVals: if (q < 0) or (q > 95): w += 2 * spacing else: w = draw_svg_text(q, font, w, 0, g) else: #Generate glyph table wmax = 0 for p in range(0, 10): w = 0 v = spacing * (15 * p - 67) for q in range(0, 10): r = p * 10 + q if (r < 0) or (r > 95): w += 5 * spacing else: w = draw_svg_text(r, clearfont, w, v, g) w = draw_svg_text(r, font, w, v, g) w += 5 * spacing if w > wmax: wmax = w w = wmax # Translate group to center of view, approximately view_center = computePointInNode(list(self.view_center), self.current_layer) t = 'translate(' + str(view_center[0] - scale * w / 2) + ',' + str( view_center[1]) + ')' if scale != 1: t += ' scale(' + str(scale) + ')' g.set('transform', t)
def effect( self ): # Embed text in group to make manipulation easier: g_attribs = {inkex.addNS('label','inkscape'):'Hershey Text' } g = inkex.etree.SubElement(self.current_layer, 'g', g_attribs) scale = self.unittouu('1px') # convert to document units font = eval('hersheydata.' + str(self.options.fontface)) clearfont = hersheydata.futural #Baseline: modernized roman simplex from JHF distribution. w = 0 #Initial spacing offset spacing = 3 # spacing between letters if self.options.action == "render": #evaluate text string letterVals = [ord(q) - 32 for q in self.options.text] for q in letterVals: if (q < 0) or (q > 95): w += 2*spacing else: w = draw_svg_text(q, font, w, 0, g) else: #Generate glyph table wmax = 0; for p in range(0,10): w = 0 v = spacing * (15*p - 67 ) for q in range(0,10): r = p*10 + q if (r < 0) or (r > 95): w += 5*spacing else: w = draw_svg_text(r, clearfont, w, v, g) w = draw_svg_text(r, font, w, v, g) w += 5*spacing if w > wmax: wmax = w w = wmax # Translate group to center of view, approximately view_center = computePointInNode(list(self.view_center), self.current_layer) t = 'translate(' + str( view_center[0] - scale*w/2) + ',' + str( view_center[1] ) + ')' if scale != 1: t += ' scale(' + str(scale) + ')' g.set( 'transform',t)
def effect(self): x, y = computePointInNode(list(self.view_center), self.current_layer) bargen = getBarcode( self.options.type, text=self.options.text, height=self.options.height, document=self.document, x=x, y=y, scale=self.unittouu('1px'), ) if bargen is not None: barcode = bargen.generate() if barcode is not None: self.current_layer.append(barcode) else: sys.stderr.write("No barcode was generated\n") else: sys.stderr.write("Unable to make barcode with: " + str(self.options) + "\n")
def effect(self): opts = self.options version, error = opts.version, opts.error if version.upper() == 'M1' and error: error = None if version == '-': version = None micro = None if opts.micro == 'true' else False # Avoid problems / exceptions with choosing a Micro QR code version # If micro is False and the user chooses a MQR, an exception will be raised if version in ('M1', 'M2', 'M3', 'M4'): micro = True boost_error = opts.boost_error == 'true' want_background = opts.background == 'true' input_encoding = locale.getdefaultlocale()[1] if input_encoding and input_encoding != 'UTF-8': opts.data = unicode(opts.data, input_encoding).encode('utf8') if not micro and opts.symbol_count > 1: qrs = encoder.encode_sequence(opts.data, version=version, error=error, encoding=encoder, boost_error=boost_error, symbol_count=opts.symbol_count) else: qrs = [encoder.encode(opts.data, version=version, error=error, micro=micro, boost_error=boost_error)] centre = tuple(computePointInNode(list(self.view_center), self.current_layer)) grp_transform = 'translate' + str(centre) if opts.scale != 1: grp_transform += ' scale(%f)' % opts.scale grp = inkex.etree.SubElement(self.current_layer, inkex.addNS('g', 'svg'), transform=grp_transform) border = utils.get_default_border_size(qrs[0].version) width, height = utils.get_symbol_size(qrs[0].version, border=border) multiple_qr = len(qrs) > 1 offset = 0 for qr in qrs: g = grp if not multiple_qr else inkex.etree.SubElement(grp, inkex.addNS('g', 'svg')) if want_background: inkex.etree.SubElement(g, inkex.addNS('rect', 'svg'), width=str(width), height=str(height), x=str(offset), fill='#FFF') path_data = _create_path(qr, border, offset=offset) inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), d=path_data, stroke='#000') offset += width + border
def effect(self): self.options.size = self.unittouu(str(self.options.size) + 'px') self.options.minimum = self.unittouu(str(self.options.minimum) + 'px') s = { 'stroke-linejoin': 'miter', 'stroke-width': str(self.unittouu('1px')), 'stroke-opacity': '1.0', 'fill-opacity': '1.0', 'stroke': '#000000', 'stroke-linecap': 'butt', 'fill': 'none' } t = pturtle.pTurtle() t.pu() t.setpos(computePointInNode(list(self.view_center), self.current_layer)) t.pd() rtree(t, self.options.size, self.options.minimum, self.options.pentoggle) attribs = {'d': t.getPath(), 'style': simplestyle.formatStyle(s)} inkex.etree.SubElement(self.current_layer, inkex.addNS('path', 'svg'), attribs)
def effect(self): view_center = computePointInNode(list(self.view_center), self.current_layer) for id, node in self.selected.iteritems(): rotation = -1 if self.options.rotation == True: rotation = 1 whirl = self.options.whirl / 1000 if node.tag == inkex.addNS('path','svg'): d = node.get('d') p = cubicsuperpath.parsePath(d) for sub in p: for csp in sub: for point in csp: point[0] -= view_center[0] point[1] -= view_center[1] dist = math.sqrt((point[0] ** 2) + (point[1] ** 2)) if dist != 0: a = rotation * dist * whirl theta = math.atan2(point[1], point[0]) + a point[0] = (dist * math.cos(theta)) point[1] = (dist * math.sin(theta)) point[0] += view_center[0] point[1] += view_center[1] node.set('d',cubicsuperpath.formatPath(p))
def effect(self): length = self.unittouu(str(self.options.length) + 'px') spacing = self.unittouu(str(self.options.spacing) + 'px') angle = radians(self.options.angle) # generate points: list of (x, y) pairs points = [] x = 0 tas = tan(angle) * spacing while x < length: # move along path, generating the next 'tooth' points.append((x, 0)) points.append((x + tas, spacing)) points.append((x + spacing, spacing)) points.append((x + spacing + tas, 0)) x += spacing * 2. path = points_to_svgd(points) # Embed gear in group to make animation easier: # Translate group, Rotate path. view_center = computePointInNode(list(self.view_center), self.current_layer) t = 'translate(' + str(view_center[0]) + ',' + \ str(view_center[1]) + ')' g_attribs = { inkex.addNS('label', 'inkscape'): 'RackGear' + str(length), 'transform': t} g = inkex.etree.SubElement(self.current_layer, 'g', g_attribs) # Create SVG Path for gear style = {'stroke': '#000000', 'fill': 'none', 'stroke-width': str(self.unittouu('1px'))} gear_attribs = { 'style': simplestyle.formatStyle(style), 'd': path} gear = inkex.etree.SubElement( g, inkex.addNS('path', 'svg'), gear_attribs)
def __compose_path(self, string): self.turtle.pu() self.turtle.setpos(computePointInNode(list(self.view_center), self.current_layer)) self.turtle.pd() for c in string: if c in 'ABCDEF': self.turtle.pd() self.turtle.fd(self.options.step * (random.normalvariate(1.0, 0.01 * self.options.randomizestep))) elif c in 'GHIJKL': self.turtle.pu() self.turtle.fd(self.options.step * (random.normalvariate(1.0, 0.01 * self.options.randomizestep))) elif c == '+': self.turtle.lt(self.options.langle * (random.normalvariate(1.0, 0.01 * self.options.randomizeangle))) elif c == '-': self.turtle.rt(self.options.rangle * (random.normalvariate(1.0, 0.01 * self.options.randomizeangle))) elif c == '|': self.turtle.lt(180) elif c == '[': self.stack.append([self.turtle.getpos(), self.turtle.getheading()]) elif c == ']': self.turtle.pu() pos,heading = self.stack.pop() self.turtle.setpos(pos) self.turtle.setheading(heading)
def effect(self): # Processing of the options self.options.halfTabSizePct = self.options.tab_size / 200.0 self.options.jitterPct = self.options.jitter / 100.0 # Put in in the center of the current view view_center = computePointInNode(list(self.view_center), self.current_layer) t = 'translate(' + str( view_center[0]- self.options.puzzle_width/2.0) + ',' + \ str( view_center[1]- self.options.puzzle_height/2.0) + ')' # Create group for entire puzzle and each of the horizontal and vertical cuts g_attribs = {inkex.addNS('label','inkscape'):'Puzzle','transform':t } puzzle_group = inkex.etree.SubElement(self.current_layer, 'g', g_attribs) g_attribs = {inkex.addNS('label','inkscape'):'Rows' } rows_group = inkex.etree.SubElement(puzzle_group, 'g', g_attribs) g_attribs = {inkex.addNS('label','inkscape'):'Columns' } columns_group = inkex.etree.SubElement(puzzle_group, 'g', g_attribs) # Styles for the lines outline_style = { 'stroke': '#FF0000', 'stroke-width':str(0.1), 'fill': 'none'} horizontal_style = { 'stroke': '#00ba00', 'stroke-width':str(0.1), 'fill': 'none'} vertical_style = { 'stroke': '#0000ff', 'stroke-width':str(0.1), 'fill': 'none'} # Puzzle border rect_attribs = {'style':simplestyle.formatStyle(outline_style), inkex.addNS('label','inkscape'):'PuzzleBorder', 'x':str(0), 'y':str(0), 'width':str(self.options.puzzle_width), 'height':str(self.options.puzzle_height)} inkex.etree.SubElement(puzzle_group, inkex.addNS('rect','svg'), rect_attribs ) # Seed random, if appropriate if self.options.random_seed > 0: random.seed(self.options.random_seed) columnWidth = float(self.options.puzzle_width) / float(self.options.tiles_width) rowWidth = float(self.options.puzzle_height) / float(self.options.tiles_height) if self.options.debugMode: # Whatever debug output is needed to test things out # self.generateRandomValues() # start = Intersection(rowWidth/2.0, 0) # end = Intersection(rowWidth, columnWidth) # pathData = "M" + str(start.column) + "," + str(start.row) + " " # pathData += self.pathDataForLineWithOneTab(True, start, end) # addPath(rows_group, horizontal_style, 'debug1', pathData) return # Build array of intersection points intersections = list() for row in range(0, self.options.tiles_height + 1): intersections.append(list()) for column in range(0, self.options.tiles_width + 1): # Positions are even columns, randomized a bit if they are not the ends of the paths rowValue = row * rowWidth if row > 0 and row < self.options.tiles_height: rowValue += self.randomJitter() * float(self.options.jitter_intersection) * rowWidth columnValue = column * columnWidth if column > 0 and column < self.options.tiles_width: columnValue += self.randomJitter() * float(self.options.jitter_intersection) * columnWidth intersections[row].append(Intersection(rowValue, columnValue)) # Horizontal Lines - go through each row and make connections between the column points for row in range(1, self.options.tiles_height): # Paths should alternate which side they start on, set up the column range appropriately columnRange = range(0, self.options.tiles_width) nextColumnDirection = 1 if (row % 2) == 0: columnRange = range(self.options.tiles_width, 0, -1) nextColumnDirection = -1 firstColumn = True for column in columnRange: if firstColumn: pathData = "M" + str(intersections[row][column].column) + "," + str(intersections[row][column].row) + " " pathData += self.pathDataForLineWithOneTab(firstColumn, intersections[row][column], # Starting point intersections[row][column + nextColumnDirection]) # Ending point firstColumn = False addPath(rows_group, horizontal_style, 'row'+str(row), pathData) # Vertical Lines - go through each column and make connections between the row points for column in range(1, self.options.tiles_width): # Paths should alternate which side they start on, set up the row range appropriately rowRange = range(0, self.options.tiles_height) nextRowDirection = 1 if (column % 2) == 0: rowRange = range(self.options.tiles_height, 0, -1) nextRowDirection = -1 firstRow = True for row in rowRange: if firstRow: pathData = "M" + str(intersections[row][column].column) + "," + str(intersections[row][column].row) + " " pathData += self.pathDataForLineWithOneTab(firstRow, intersections[row][column], # Starting point intersections[row + nextRowDirection][column]) # Ending point firstRow = False addPath(columns_group, vertical_style, 'column'+str(column), pathData)
def effect(self): so = self.options #shorthand #INITIALISE AND LOAD DATA obj = Obj() #create the object file = get_filename(so) #get the file to load data from get_obj_data(obj, file) #load data from the obj file obj.set_type(so) #set the type (face or edge) as per the settings scale = self.unittouu('1px') # convert to document units st = Style(so) #initialise style fill_col = (so.f_r, so.f_g, so.f_b) #colour tuple for the face fill lighting = normalise((so.lv_x, -so.lv_y, so.lv_z)) #unit light vector #INKSCAPE GROUP TO CONTAIN THE POLYHEDRON #Put in in the centre of the current view view_center = computePointInNode(list(self.view_center), self.current_layer) poly_transform = 'translate(' + str(view_center[0]) + ',' + str( view_center[1]) + ')' if scale != 1: poly_transform += ' scale(' + str(scale) + ')' #we will put all the rotations in the object name, so it can be repeated in poly_name = obj.name + ':' + make_rotation_log(so) poly_attribs = { inkex.addNS('label', 'inkscape'): poly_name, 'transform': poly_transform } poly = inkex.etree.SubElement( self.current_layer, 'g', poly_attribs) #the group to put everything in #TRANSFORMATION OF THE OBJECT (ROTATION, SCALE, ETC) trans_mat = mat(identity( 3, float)) #init. trans matrix as identity matrix for i in range(1, 7): #for each rotation axis = eval('so.r' + str(i) + '_ax') angle = eval('so.r' + str(i) + '_ang') * pi / 180 trans_mat = rotate(trans_mat, angle, axis) trans_mat = trans_mat * so.scl #scale by linear factor (do this only after the transforms to reduce round-off) transformed_pts = get_transformed_pts( obj.vtx, trans_mat ) #the points as projected in the z-axis onto the viewplane #RENDERING OF THE OBJECT if so.show == 'vtx': for i in range(len(transformed_pts)): draw_SVG_dot( [transformed_pts[i][0], transformed_pts[i][1]], st, 'Point' + str(i), poly) #plot points using transformed_pts x and y coords elif so.show == 'edg': if obj.type == 'face': #we must generate the edge list from the faces edge_list = make_edge_list(obj.fce) else: #we already have an edge list edge_list = obj.edg draw_edges(edge_list, transformed_pts, st, poly) elif so.show == 'fce': if obj.type == 'face': #we have a face list z_list = [] for i in range(len(obj.fce)): face = obj.fce[i] #the face we are dealing with norm = get_unit_normal( transformed_pts, face, so.cw_wound) #get the normal vector to the face angle = get_angle( norm, lighting ) #get the angle between the normal and the lighting vector z_sort_param = get_z_sort_param(transformed_pts, face, so.z_sort) if so.back or norm[ 2] > 0: # include all polygons or just the front-facing ones as needed z_list.append( (z_sort_param, angle, norm, i) ) #record the maximum z-value of the face and angle to light, along with the face ID and normal z_list.sort(lambda x, y: cmp(x[0], y[0]) ) #sort by ascending sort parameter of the face draw_faces(z_list, transformed_pts, obj, so.shade, fill_col, st, poly) else: #we cannot generate a list of faces from the edges without a lot of computation inkex.errormsg( _('Face Data Not Found. Ensure file contains face data, and check the file is imported as "Face-Specified" under the "Model File" tab.\n' )) else: inkex.errormsg(_('Internal Error. No view type selected\n'))
def effect(self): obj = self.current_layer offset = computePointInNode(list(self.view_center), obj) draw(offset, self.options.size, self.options.num_curves, obj)
def effect(self): so = self.options#shorthand #INITIALISE AND LOAD DATA obj = Obj() #create the object file = get_filename(so)#get the file to load data from get_obj_data(obj, file)#load data from the obj file obj.set_type(so)#set the type (face or edge) as per the settings scale = self.unittouu('1px') # convert to document units st = Style(so) #initialise style fill_col = (so.f_r, so.f_g, so.f_b) #colour tuple for the face fill lighting = normalise( (so.lv_x,-so.lv_y,so.lv_z) ) #unit light vector #INKSCAPE GROUP TO CONTAIN THE POLYHEDRON #Put in in the centre of the current view view_center = computePointInNode(list(self.view_center), self.current_layer) poly_transform = 'translate(' + str( view_center[0]) + ',' + str( view_center[1]) + ')' if scale != 1: poly_transform += ' scale(' + str(scale) + ')' #we will put all the rotations in the object name, so it can be repeated in poly_name = obj.name+':'+make_rotation_log(so) poly_attribs = {inkex.addNS('label','inkscape'):poly_name, 'transform':poly_transform } poly = inkex.etree.SubElement(self.current_layer, 'g', poly_attribs)#the group to put everything in #TRANSFORMATION OF THE OBJECT (ROTATION, SCALE, ETC) trans_mat = mat(identity(3, float)) #init. trans matrix as identity matrix for i in range(1, 7):#for each rotation axis = eval('so.r'+str(i)+'_ax') angle = eval('so.r'+str(i)+'_ang') *pi/180 trans_mat = rotate(trans_mat, angle, axis) trans_mat = trans_mat*so.scl #scale by linear factor (do this only after the transforms to reduce round-off) transformed_pts = get_transformed_pts(obj.vtx, trans_mat) #the points as projected in the z-axis onto the viewplane #RENDERING OF THE OBJECT if so.show == 'vtx': for i in range(len(transformed_pts)): draw_SVG_dot([transformed_pts[i][0],transformed_pts[i][1]], st, 'Point'+str(i), poly)#plot points using transformed_pts x and y coords elif so.show == 'edg': if obj.type == 'face':#we must generate the edge list from the faces edge_list = make_edge_list(obj.fce) else:#we already have an edge list edge_list = obj.edg draw_edges( edge_list, transformed_pts, st, poly) elif so.show == 'fce': if obj.type == 'face':#we have a face list z_list = [] for i in range(len(obj.fce)): face = obj.fce[i] #the face we are dealing with norm = get_unit_normal(transformed_pts, face, so.cw_wound) #get the normal vector to the face angle = get_angle( norm, lighting )#get the angle between the normal and the lighting vector z_sort_param = get_z_sort_param(transformed_pts, face, so.z_sort) if so.back or norm[2] > 0: # include all polygons or just the front-facing ones as needed z_list.append((z_sort_param, angle, norm, i))#record the maximum z-value of the face and angle to light, along with the face ID and normal z_list.sort(lambda x, y: cmp(x[0],y[0])) #sort by ascending sort parameter of the face draw_faces( z_list, transformed_pts, obj, so.shade, fill_col, st, poly) else:#we cannot generate a list of faces from the edges without a lot of computation inkex.errormsg(_('Face Data Not Found. Ensure file contains face data, and check the file is imported as "Face-Specified" under the "Model File" tab.\n')) else: inkex.errormsg(_('Internal Error. No view type selected\n'))
def effect(self): self.options.dr = self.unittouu(str(self.options.dr) + 'px') self.options.r_divs_th = self.unittouu(str(self.options.r_divs_th) + 'px') self.options.r_subdivs_th = self.unittouu(str(self.options.r_subdivs_th) + 'px') self.options.a_divs_th = self.unittouu(str(self.options.a_divs_th) + 'px') self.options.a_subdivs_th = self.unittouu(str(self.options.a_subdivs_th) + 'px') self.options.c_dot_dia = self.unittouu(str(self.options.c_dot_dia) + 'px') self.options.a_label_size = self.unittouu(str(self.options.a_label_size) + 'px') self.options.a_label_outset = self.unittouu(str(self.options.a_label_outset) + 'px') # Embed grid in group #Put in in the centre of the current view view_center = computePointInNode(list(self.view_center), self.current_layer) t = 'translate(' + str( view_center[0] ) + ',' + str( view_center[1] ) + ')' g_attribs = {inkex.addNS('label','inkscape'):'Grid_Polar:R' + str( self.options.r_divs )+':A'+str( self.options.a_divs ), 'transform':t } grid = inkex.etree.SubElement(self.current_layer, 'g', g_attribs) dr = self.options.dr #Distance between neighbouring circles dtheta = 2 * pi / self.options.a_divs_cent #Angular change between adjacent radial lines at centre rmax = self.options.r_divs * dr #Create SVG circles for i in range(1, self.options.r_divs+1): draw_SVG_circle(i*dr, 0, 0, #major div circles self.options.r_divs_th, 'none', 'MajorDivCircle'+str(i)+':R'+str(i*dr), grid) if self.options.r_log: #logarithmic subdivisions for j in range (2, self.options.r_subdivs): draw_SVG_circle(i*dr-(1-log(j, self.options.r_subdivs))*dr, #minor div circles 0, 0, self.options.r_subdivs_th, 'none', 'MinorDivCircle'+str(i)+':Log'+str(j), grid) else: #linear subdivs for j in range (1, self.options.r_subdivs): draw_SVG_circle(i*dr-j*dr/self.options.r_subdivs, #minor div circles 0, 0, self.options.r_subdivs_th, 'none', 'MinorDivCircle'+str(i)+':R'+str(i*dr), grid) if self.options.a_divs == self.options.a_divs_cent: #the lines can go from the centre to the edge for i in range(0, self.options.a_divs): draw_SVG_line(0, 0, rmax*sin(i*dtheta), rmax*cos(i*dtheta), self.options.a_divs_th, 'RadialGridline'+str(i), grid) else: #we need separate lines for i in range(0, self.options.a_divs_cent): #lines that go to the first circle draw_SVG_line(0, 0, dr*sin(i*dtheta), dr*cos(i*dtheta), self.options.a_divs_th, 'RadialGridline'+str(i), grid) dtheta = 2 * pi / self.options.a_divs #work out the angle change for outer lines for i in range(0, self.options.a_divs): #lines that go from there to the edge draw_SVG_line( dr*sin(i*dtheta+pi/2.0), dr*cos(i*dtheta+pi/2.0), rmax*sin(i*dtheta+pi/2.0), rmax*cos(i*dtheta+pi/2.0), self.options.a_divs_th, 'RadialGridline'+str(i), grid) if self.options.a_subdivs > 1: #draw angular subdivs for i in range(0, self.options.a_divs): #for each major divison for j in range(1, self.options.a_subdivs): #draw the subdivisions angle = i*dtheta-j*dtheta/self.options.a_subdivs+pi/2.0 # the angle of the subdivion line draw_SVG_line(dr*self.options.a_subdivs_cent*sin(angle), dr*self.options.a_subdivs_cent*cos(angle), rmax*sin(angle), rmax*cos(angle), self.options.a_subdivs_th, 'RadialMinorGridline'+str(i), grid) if self.options.c_dot_dia <> 0: #if a non-zero diameter, draw the centre dot draw_SVG_circle(self.options.c_dot_dia /2.0, 0, 0, 0, '#000000', 'CentreDot', grid) if self.options.a_labels == 'deg': label_radius = rmax+self.options.a_label_outset #radius of label centres label_size = self.options.a_label_size numeral_size = 0.73*label_size #numerals appear to be 0.73 the height of the nominal pixel size of the font in "Sans" for i in range(0, self.options.a_divs):#self.options.a_divs): #radial line labels draw_SVG_label_centred(sin(i*dtheta+pi/2.0)*label_radius, #0 at the RHS, mathematical style cos(i*dtheta+pi/2.0)*label_radius+ numeral_size/2.0, #centre the text vertically str(i*360/self.options.a_divs), label_size, 'Label'+str(i), grid)
def effect(self): self.options.primaryr = self.unittouu( str(self.options.primaryr) + 'px') self.options.secondaryr = self.unittouu( str(self.options.secondaryr) + 'px') self.options.penr = self.unittouu(str(self.options.penr) + 'px') if self.options.secondaryr == 0: return if self.options.quality == 0: return if (self.options.gearplacement.strip(' ').lower().startswith('outside') ): a = self.options.primaryr + self.options.secondaryr flip = -1 else: a = self.options.primaryr - self.options.secondaryr flip = 1 ratio = a / self.options.secondaryr if ratio == 0: return scale = 2 * math.pi / (ratio * self.options.quality) rotation = -math.pi * self.options.rotation / 180 new = inkex.etree.Element(inkex.addNS('path', 'svg')) s = { 'stroke': '#000000', 'fill': 'none', 'stroke-width': str(self.unittouu('1px')) } new.set('style', simplestyle.formatStyle(s)) pathString = '' maxPointCount = 1000 for i in range(maxPointCount): theta = i * scale view_center = computePointInNode(list(self.view_center), self.current_layer) x = a * math.cos(theta + rotation) + \ self.options.penr * math.cos(ratio * theta + rotation) * flip + \ view_center[0] y = a * math.sin(theta + rotation) - \ self.options.penr * math.sin(ratio * theta + rotation) + \ view_center[1] dx = (-a * math.sin(theta + rotation) - \ ratio * self.options.penr * math.sin(ratio * theta + rotation) * flip) * scale / 3 dy = (a * math.cos(theta + rotation) - \ ratio * self.options.penr * math.cos(ratio * theta + rotation)) * scale / 3 if i <= 0: pathString += 'M ' + str(x) + ',' + str(y) + ' C ' + str( x + dx) + ',' + str(y + dy) + ' ' else: pathString += str(x - dx) + ',' + str(y - dy) + ' ' + str( x) + ',' + str(y) if math.fmod(i / ratio, self.options.quality ) == 0 and i % self.options.quality == 0: pathString += 'Z' break else: if i == maxPointCount - 1: pass # we reached the allowed maximum of points, stop here else: pathString += ' C ' + str(x + dx) + ',' + str(y + dy) + ' ' new.set('d', pathString) self.current_layer.append(new)
def effect(self): tri = self.current_layer offset = computePointInNode( list(self.view_center), self.current_layer) #the offset require to centre the triangle self.options.s_a = self.unittouu(str(self.options.s_a) + 'px') self.options.s_b = self.unittouu(str(self.options.s_b) + 'px') self.options.s_c = self.unittouu(str(self.options.s_c) + 'px') stroke_width = self.unittouu('2px') if self.options.mode == '3_sides': s_a = self.options.s_a s_b = self.options.s_b s_c = self.options.s_c draw_tri_from_3_sides(s_a, s_b, s_c, offset, stroke_width, tri) elif self.options.mode == 's_ab_a_c': s_a = self.options.s_a s_b = self.options.s_b a_c = self.options.a_c * pi / 180 #in rad s_c = third_side_from_enclosed_angle(s_a, s_b, a_c) draw_tri_from_3_sides(s_a, s_b, s_c, offset, stroke_width, tri) elif self.options.mode == 's_ab_a_a': s_a = self.options.s_a s_b = self.options.s_b a_a = self.options.a_a * pi / 180 #in rad if (a_a < pi / 2.0) and (s_a < s_b) and ( s_a > s_b * sin(a_a)): #this is an ambigous case ambiguous = True #we will give both answers else: ambiguous = False sin_a_b = s_b * sin(a_a) / s_a if (sin_a_b <= 1) and (sin_a_b >= -1): #check the solution is possible a_b = asin(sin_a_b) #acute solution a_c = pi - a_a - a_b error = False else: sys.stderr.write('Error:Invalid Triangle Specifications.\n' ) #signal an error error = True if not (error) and (a_b < pi) and ( a_c < pi ): #check that the solution is valid, if so draw acute solution s_c = third_side_from_enclosed_angle(s_a, s_b, a_c) draw_tri_from_3_sides(s_a, s_b, s_c, offset, stroke_width, tri) if not (error) and ((a_b > pi) or (a_c > pi) or ambiguous): #we want the obtuse solution a_b = pi - a_b a_c = pi - a_a - a_b s_c = third_side_from_enclosed_angle(s_a, s_b, a_c) draw_tri_from_3_sides(s_a, s_b, s_c, offset, stroke_width, tri) elif self.options.mode == 's_a_a_ab': s_a = self.options.s_a a_a = self.options.a_a * pi / 180 #in rad a_b = self.options.a_b * pi / 180 #in rad a_c = pi - a_a - a_b s_b = s_a * sin(a_b) / sin(a_a) s_c = s_a * sin(a_c) / sin(a_a) draw_tri_from_3_sides(s_a, s_b, s_c, offset, stroke_width, tri) elif self.options.mode == 's_c_a_ab': s_c = self.options.s_c a_a = self.options.a_a * pi / 180 #in rad a_b = self.options.a_b * pi / 180 #in rad a_c = pi - a_a - a_b s_a = s_c * sin(a_a) / sin(a_c) s_b = s_c * sin(a_b) / sin(a_c) draw_tri_from_3_sides(s_a, s_b, s_c, offset, stroke_width, tri)
def effect(self): self.options.border_th = self.unittouu(str(self.options.border_th) + 'px') self.options.dx = self.unittouu(str(self.options.dx) + 'px') self.options.x_divs_th = self.unittouu(str(self.options.x_divs_th) + 'px') self.options.x_subdivs_th = self.unittouu(str(self.options.x_subdivs_th) + 'px') self.options.x_subsubdivs_th = self.unittouu(str(self.options.x_subsubdivs_th) + 'px') self.options.dy = self.unittouu(str(self.options.dy) + 'px') self.options.y_divs_th = self.unittouu(str(self.options.y_divs_th) + 'px') self.options.y_subdivs_th = self.unittouu(str(self.options.y_subdivs_th) + 'px') self.options.y_subsubdivs_th = self.unittouu(str(self.options.y_subsubdivs_th) + 'px') #find the pixel dimensions of the overall grid ymax = self.options.dy * self.options.y_divs xmax = self.options.dx * self.options.x_divs # Embed grid in group #Put in in the centre of the current view view_center = computePointInNode(list(self.view_center), self.current_layer) t = 'translate(' + str( view_center[0]- xmax/2.0) + ',' + \ str( view_center[1]- ymax/2.0) + ')' g_attribs = {inkex.addNS('label','inkscape'):'Grid_Polar:X' + \ str( self.options.x_divs )+':Y'+str( self.options.y_divs ), 'transform':t } grid = inkex.etree.SubElement(self.current_layer, 'g', g_attribs) #Group for major x gridlines g_attribs = {inkex.addNS('label','inkscape'):'MajorXGridlines'} majglx = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for major y gridlines g_attribs = {inkex.addNS('label','inkscape'):'MajorYGridlines'} majgly = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for minor x gridlines if self.options.x_subdivs > 1:#if there are any minor x gridlines g_attribs = {inkex.addNS('label','inkscape'):'MinorXGridlines'} minglx = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for subminor x gridlines if self.options.x_subsubdivs > 1:#if there are any minor minor x gridlines g_attribs = {inkex.addNS('label','inkscape'):'SubMinorXGridlines'} mminglx = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for minor y gridlines if self.options.y_subdivs > 1:#if there are any minor y gridlines g_attribs = {inkex.addNS('label','inkscape'):'MinorYGridlines'} mingly = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for subminor y gridlines if self.options.y_subsubdivs > 1:#if there are any minor minor x gridlines g_attribs = {inkex.addNS('label','inkscape'):'SubMinorYGridlines'} mmingly = inkex.etree.SubElement(grid, 'g', g_attribs) draw_SVG_rect(0, 0, xmax, ymax, self.options.border_th, 'none', 'Border', grid) #border rectangle #DO THE X DIVISONS====================================== sd = self.options.x_subdivs #sub divs per div ssd = self.options.x_subsubdivs #subsubdivs per subdiv for i in range(0, self.options.x_divs): #Major x divisons if i>0: #dont draw first line (we made a proper border) draw_SVG_line(self.options.dx*i, 0, self.options.dx*i,ymax, self.options.x_divs_th, 'MajorXDiv'+str(i), majglx) if self.options.x_log: #log x subdivs for j in range (1, sd): if j>1: #the first loop is only for subsubdivs draw_SVG_line(self.options.dx*(i+log(j, sd)), 0, self.options.dx*(i+log(j, sd)), ymax, self.options.x_subdivs_th, 'MinorXDiv'+str(i)+':'+str(j), minglx) for k in range (1, ssd): #subsub divs if (j <= self.options.x_half_freq) or (k%2 == 0):#only draw half the subsubdivs past the half-freq point if (ssd%2 > 0) and (j > self.options.y_half_freq): #half frequency won't work with odd numbers of subsubdivs, ssd2 = ssd+1 #make even else: ssd2 = ssd #no change draw_SVG_line(self.options.dx*(i+log(j+k/float(ssd2),sd )), 0, self.options.dx*(i+log(j+k/float(ssd2),sd )), ymax, self.options.x_subsubdivs_th,'SubminorXDiv'+str(i)+':'+str(j)+':'+str(k), mminglx) else: #linear x subdivs for j in range (0, sd): if j>0: #not for the first loop (this loop is for the subsubdivs before the first subdiv) draw_SVG_line(self.options.dx*(i+j/float(sd)), 0, self.options.dx*(i+j/float(sd)), ymax, self.options.x_subdivs_th, 'MinorXDiv'+str(i)+':'+str(j), minglx) for k in range (1, ssd): #subsub divs draw_SVG_line(self.options.dx*(i+(j*ssd+k)/((float(sd)*ssd))) , 0, self.options.dx*(i+(j*ssd+k)/((float(sd)*ssd))) , ymax, self.options.x_subsubdivs_th, 'SubminorXDiv'+str(i)+':'+str(j)+':'+str(k), mminglx) #DO THE Y DIVISONS======================================== sd = self.options.y_subdivs #sub divs per div ssd = self.options.y_subsubdivs #subsubdivs per subdiv for i in range(0, self.options.y_divs): #Major y divisons if i>0:#dont draw first line (we will make a border) draw_SVG_line(0, self.options.dy*i, xmax, self.options.dy*i, self.options.y_divs_th, 'MajorYDiv'+str(i), majgly) if self.options.y_log: #log y subdivs for j in range (1, sd): if j>1: #the first loop is only for subsubdivs draw_SVG_line(0, self.options.dy*(i+1-log(j,sd)), xmax, self.options.dy*(i+1-log(j,sd)), self.options.y_subdivs_th, 'MinorXDiv'+str(i)+':'+str(j), mingly) for k in range (1, ssd): #subsub divs if (j <= self.options.y_half_freq) or (k%2 == 0):#only draw half the subsubdivs past the half-freq point if (ssd%2 > 0) and (j > self.options.y_half_freq): #half frequency won't work with odd numbers of subsubdivs, ssd2 = ssd+1 else: ssd2 = ssd #no change draw_SVG_line(0, self.options.dx*(i+1-log(j+k/float(ssd2),sd )), xmax, self.options.dx*(i+1-log(j+k/float(ssd2),sd )), self.options.y_subsubdivs_th, 'SubminorXDiv'+str(i)+':'+str(j)+':'+str(k), mmingly) else: #linear y subdivs for j in range (0, self.options.y_subdivs): if j>0:#not for the first loop (this loop is for the subsubdivs before the first subdiv) draw_SVG_line(0, self.options.dy*(i+j/float(sd)), xmax, self.options.dy*(i+j/float(sd)), self.options.y_subdivs_th, 'MinorXYiv'+str(i)+':'+str(j), mingly) for k in range (1, ssd): #subsub divs draw_SVG_line(0, self.options.dy*(i+(j*ssd+k)/((float(sd)*ssd))), xmax, self.options.dy*(i+(j*ssd+k)/((float(sd)*ssd))), self.options.y_subsubdivs_th, 'SubminorXDiv'+str(i)+':'+str(j)+':'+str(k), mmingly)
def effect( self ): OutputGenerated = False # Embed text in group to make manipulation easier: g_attribs = {inkex.addNS('label','inkscape'):'Hershey Text' } g = inkex.etree.SubElement(self.current_layer, 'g', g_attribs) scale = self.unittouu('1px') # convert to document units font = eval('hersheydata.' + str(self.options.fontface)) clearfont = hersheydata.futural #Baseline: modernized roman simplex from JHF distribution. w = 0 #Initial spacing offset v = 0 #Initial vertical offset text = self.options.text if self.options.action == "render": #evaluate text string letterVals = [ord(q) for q in text] i = 0 for q in letterVals: if q == 10: v += FONT_GROUP_V_SPACING w = 0 elif (q <= 32): w += 2 * spacing else: w = self.draw_svg_text(q, font, w, v, g) OutputGenerated = True if (q == 32 or q == 7) and (int(self.options.boxwidth) > 0): tokenw = 0 for j in range(len(letterVals) - i - 1): ch = letterVals[j + i + 1] if (ch == 32 or ch == 7): break tokenw = self.svg_char_width(ch, font, tokenw) if (w > 0) and ((tokenw + w) > int(self.options.boxwidth)): v += FONT_GROUP_V_SPACING w = 0 break i += 1 elif self.options.action == 'sample': w,v = self.render_table_of_all_fonts( 'group_allfonts', g, spacing, clearfont ) OutputGenerated = True scale *= 0.4 #Typically scales to about A4/US Letter size else: #Generate glyph table wmax = 0; for p in range(0,10): w = 0 v = spacing * (15*p - 67 ) for q in range(0,10): r = p*10 + q if (r <= 32) or (r > 127): w += 5*spacing else: w = self.draw_svg_text(r, clearfont, w, v, g) w = self.draw_svg_text(r, font, w, v, g) w += 5 * spacing if w > wmax: wmax = w w = wmax OutputGenerated = True # Translate group to center of view, approximately view_center = computePointInNode(list(self.view_center), self.current_layer) t = 'translate(' + str( view_center[0] - scale*w/2) + ',' + str( view_center[1] - scale*v/2 ) + ')' if scale != 1: t += ' scale(' + str(scale) + ')' g.set( 'transform',t) # inkex.debug(self.options.boxwidth) # inkex.debug(w) if not OutputGenerated: self.current_layer.remove(g) #remove empty group, if no SVG was generated.
def effect(self): self.options.dx = self.unittouu(str(self.options.dx) + 'px') self.options.divs_th = self.unittouu(str(self.options.divs_th) + 'px') self.options.subdivs_th = self.unittouu(str(self.options.subdivs_th) + 'px') self.options.subsubdivs_th = self.unittouu(str(self.options.subsubdivs_th) + 'px') self.options.border_th = self.unittouu(str(self.options.border_th) + 'px') #Can't generate a grid too flat #If the Y dimension is smallest than half the X dimension, fix it. if self.options.y_divs<((self.options.x_divs+1)/2): self.options.y_divs=int((self.options.x_divs+1)/2) #Find the pixel dimensions of the overall grid xmax = self.options.dx * (2*self.options.x_divs) ymax = self.options.dx * (2*self.options.y_divs) / 0.866025 #Embed grid in group #Put in in the centre of the current view view_center = computePointInNode(list(self.view_center), self.current_layer) t = 'translate(' + str( view_center[0]- xmax/2.0) + ',' + \ str( view_center[1]- ymax/2.0) + ')' g_attribs = {inkex.addNS('label','inkscape'):'Grid_Polar:X' + \ str( self.options.x_divs )+':Y'+str( self.options.y_divs ), 'transform':t } grid = inkex.etree.SubElement(self.current_layer, 'g', g_attribs) #Group for major x gridlines g_attribs = {inkex.addNS('label','inkscape'):'MajorXGridlines'} majglx = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for major y gridlines g_attribs = {inkex.addNS('label','inkscape'):'MajorYGridlines'} majgly = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for major z gridlines g_attribs = {inkex.addNS('label','inkscape'):'MajorZGridlines'} majglz = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for minor x gridlines if self.options.subdivs > 1:#if there are any minor x gridlines g_attribs = {inkex.addNS('label','inkscape'):'MinorXGridlines'} minglx = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for subminor x gridlines if self.options.subsubdivs > 1:#if there are any minor minor x gridlines g_attribs = {inkex.addNS('label','inkscape'):'SubMinorXGridlines'} mminglx = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for minor y gridlines if self.options.subdivs > 1:#if there are any minor y gridlines g_attribs = {inkex.addNS('label','inkscape'):'MinorYGridlines'} mingly = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for subminor y gridlines if self.options.subsubdivs > 1:#if there are any minor minor x gridlines g_attribs = {inkex.addNS('label','inkscape'):'SubMinorYGridlines'} mmingly = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for minor z gridlines if self.options.subdivs > 1:#if there are any minor y gridlines g_attribs = {inkex.addNS('label','inkscape'):'MinorZGridlines'} minglz = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for subminor z gridlines if self.options.subsubdivs > 1:#if there are any minor minor x gridlines g_attribs = {inkex.addNS('label','inkscape'):'SubMinorZGridlines'} mminglz = inkex.etree.SubElement(grid, 'g', g_attribs) draw_SVG_rect(0, 0, xmax, ymax, self.options.border_th, 'none', 'Border', grid) #Border of grid #X DIVISION #Shortcuts for divisions sd = self.options.subdivs ssd = self.options.subsubdivs #Initializing variable cpt_div=0 cpt_subdiv=0 cpt_subsubdiv=0 com_div=0 com_subdiv=0 com_subsubdiv=0 for i in range(1, (2*self.options.x_divs*sd*ssd)): cpt_subsubdiv=cpt_subsubdiv+1 com_subsubdiv=1 if cpt_subsubdiv==self.options.subsubdivs: cpt_subsubdiv=0 cpt_subdiv=cpt_subdiv+1 com_subsubdiv=0 com_subdiv=1 com_div=0 if cpt_subdiv==self.options.subdivs: cpt_subdiv=0 com_subsubdiv=0 com_subdiv=0 com_div=1 if com_subsubdiv==1: draw_SVG_line(self.options.dx*i/sd/ssd, 0, self.options.dx*i/sd/ssd,ymax, self.options.subsubdivs_th, 'MajorXDiv'+str(i), mminglx) if com_subdiv==1: com_subdiv=0 draw_SVG_line(self.options.dx*i/sd/ssd, 0, self.options.dx*i/sd/ssd,ymax, self.options.subdivs_th, 'MajorXDiv'+str(i), minglx) if com_div==1: com_div=0 draw_SVG_line(self.options.dx*i/sd/ssd, 0, self.options.dx*i/sd/ssd,ymax, self.options.divs_th, 'MajorXDiv'+str(i), majglx) #Y DIVISONS #Shortcuts for divisions sd = self.options.subdivs ssd = self.options.subsubdivs taille=self.options.dx/sd/ssd #Size of unity nb_ligne=(self.options.x_divs+self.options.y_divs)*self.options.subdivs*self.options.subsubdivs #Global number of lines nb_ligne_x=self.options.x_divs*self.options.subdivs*self.options.subsubdivs #Number of lines X nb_ligne_y=self.options.y_divs*self.options.subdivs*self.options.subsubdivs #Number of lines Y #Initializing variable cpt_div=0 cpt_subdiv=0 cpt_subsubdiv=0 com_div=0 com_subdiv=0 com_subsubdiv=0 for l in range(1, int(nb_ligne*4)): cpt_subsubdiv=cpt_subsubdiv+1 com_subsubdiv=1 if cpt_subsubdiv==self.options.subsubdivs: cpt_subsubdiv=0 cpt_subdiv=cpt_subdiv+1 com_subsubdiv=0 com_subdiv=1 com_div=0 if cpt_subdiv==self.options.subdivs: cpt_subdiv=0 com_subsubdiv=0 com_subdiv=0 com_div=1 if ((2*l)-1)< (2*nb_ligne_x): txa=taille*((2*l)-1) tya=ymax txb=0 tyb=ymax-(taille)/(2*0.866025)-(taille*((l-1))/(0.866025)) if com_subsubdiv==1: draw_SVG_line(txa, tya, txb,tyb, self.options.subsubdivs_th, 'MajorYDiv'+str(i), mmingly) draw_SVG_line(xmax-txa, tya, xmax-txb,tyb, self.options.subsubdivs_th, 'MajorZDiv'+str(l), mminglz) if com_subdiv==1: com_subdiv=0 draw_SVG_line(txa, tya, txb,tyb, self.options.subdivs_th, 'MajorYDiv'+str(i), mingly) draw_SVG_line(xmax-txa, tya, xmax-txb,tyb, self.options.subdivs_th, 'MajorZDiv'+str(l), minglz) if com_div==1: com_div=0 draw_SVG_line(txa, tya, txb,tyb, self.options.divs_th, 'MajorYDiv'+str(i), majgly) draw_SVG_line(xmax-txa, tya, xmax-txb,tyb, self.options.divs_th, 'MajorZDiv'+str(l), majglz) if ((2*l)-1)==(2*nb_ligne_x): txa=taille*((2*l)-1) tya=ymax txb=0 tyb=ymax-(taille)/(2*0.866025)-(taille*((l-1))/(0.866025)) if com_subsubdiv==1: draw_SVG_line(txa, tya, txb,tyb, self.options.subsubdivs_th, 'MajorYDiv'+str(i), mmingly) draw_SVG_line(xmax-txa, tya, xmax-txb,tyb, self.options.subsubdivs_th, 'MajorZDiv'+str(l), mminglz) if com_subdiv==1: com_subdiv=0 draw_SVG_line(txa, tya, txb,tyb, self.options.subdivs_th, 'MajorYDiv'+str(i), mingly) draw_SVG_line(xmax-txa, tya, xmax-txb,tyb, self.options.subdivs_th, 'MajorZDiv'+str(l), minglz) if com_div==1: com_div=0 draw_SVG_line(txa, tya, txb,tyb, self.options.divs_th, 'MajorYDiv'+str(i), majgly) draw_SVG_line(xmax-txa, tya, xmax-txb,tyb, self.options.divs_th, 'MajorZDiv'+str(l), majglz) if ((2*l)-1)> (2*nb_ligne_x): txa=xmax tya=ymax-(taille)/(2*0.866025)-(taille*((l-1-((2*nb_ligne_x)/2)))/(0.866025)) txb=0 tyb=ymax-(taille)/(2*0.866025)-(taille*((l-1))/(0.866025)) if tyb<=0: txa=xmax tya=ymax-(taille)/(2*0.866025)-(taille*((l-1-((2*nb_ligne_x)/2)))/(0.866025)) txb=taille*((2*(l-(2*nb_ligne_y))-1)) tyb=0 if txb<xmax: if com_subsubdiv==1: draw_SVG_line(txa, tya, txb,tyb, self.options.subsubdivs_th, 'MajorYDiv'+str(i), mmingly) draw_SVG_line(xmax-txa, tya, xmax-txb,tyb, self.options.subsubdivs_th, 'MajorZDiv'+str(l), mminglz) if com_subdiv==1: com_subdiv=0 draw_SVG_line(txa, tya, txb,tyb, self.options.subdivs_th, 'MajorYDiv'+str(i), mingly) draw_SVG_line(xmax-txa, tya, xmax-txb,tyb, self.options.subdivs_th, 'MajorZDiv'+str(l), minglz) if com_div==1: com_div=0 draw_SVG_line(txa, tya, txb,tyb, self.options.divs_th, 'MajorYDiv'+str(i), majgly) draw_SVG_line(xmax-txa, tya, xmax-txb,tyb, self.options.divs_th, 'MajorZDiv'+str(l), majglz) else: if txb<xmax: if com_subsubdiv==1: draw_SVG_line(txa, tya, txb,tyb, self.options.subsubdivs_th, 'MajorYDiv'+str(i), mmingly) draw_SVG_line(xmax-txa, tya, xmax-txb,tyb, self.options.subsubdivs_th, 'MajorZDiv'+str(l), mminglz) if com_subdiv==1: com_subdiv=0 draw_SVG_line(txa, tya, txb,tyb, self.options.subdivs_th, 'MajorYDiv'+str(i), mingly) draw_SVG_line(xmax-txa, tya, xmax-txb,tyb, self.options.subdivs_th, 'MajorZDiv'+str(l), minglz) if com_div==1: com_div=0 draw_SVG_line(txa, tya, txb,tyb, self.options.divs_th, 'MajorYDiv'+str(i), majgly) draw_SVG_line(xmax-txa, tya, xmax-txb,tyb, self.options.divs_th, 'MajorZDiv'+str(l), majglz)
def effect(self): teeth = self.options.teeth pitch = self.unittouu( str(self.options.pitch) + self.options.unit) angle = self.options.angle # Angle of tangent to tooth at circular pitch wrt radial line. centerdiameter = self.unittouu( str(self.options.centerdiameter) + self.options.unit) # print >>sys.stderr, "Teeth: %s\n" % teeth two_pi = 2.0 * pi # Pitch (circular pitch): Length of the arc from one tooth to the next) # Pitch diameter: Diameter of pitch circle. pitch_diameter = float( teeth ) * pitch / pi pitch_radius = pitch_diameter / 2.0 # Base Circle base_diameter = pitch_diameter * cos( radians( angle ) ) base_radius = base_diameter / 2.0 # Diametrial pitch: Number of teeth per unit length. pitch_diametrial = float( teeth )/ pitch_diameter # Addendum: Radial distance from pitch circle to outside circle. addendum = 1.0 / pitch_diametrial # Outer Circle outer_radius = pitch_radius + addendum outer_diameter = outer_radius * 2.0 # Tooth thickness: Tooth width along pitch circle. tooth = ( pi * pitch_diameter ) / ( 2.0 * float( teeth ) ) # Undercut? undercut = (2.0 / ( sin( radians( angle ) ) ** 2)) needs_undercut = teeth < undercut # Clearance: Radial distance between top of tooth on one gear to bottom of gap on another. clearance = 0.0 # Dedendum: Radial distance from pitch circle to root diameter. dedendum = addendum + clearance # Root diameter: Diameter of bottom of tooth spaces. root_radius = pitch_radius - dedendum root_diameter = root_radius * 2.0 half_thick_angle = two_pi / (4.0 * float( teeth ) ) pitch_to_base_angle = involute_intersect_angle( base_radius, pitch_radius ) pitch_to_outer_angle = involute_intersect_angle( base_radius, outer_radius ) - pitch_to_base_angle centers = [(x * two_pi / float( teeth) ) for x in range( teeth ) ] points = [] for c in centers: # Angles pitch1 = c - half_thick_angle base1 = pitch1 - pitch_to_base_angle outer1 = pitch1 + pitch_to_outer_angle pitch2 = c + half_thick_angle base2 = pitch2 + pitch_to_base_angle outer2 = pitch2 - pitch_to_outer_angle # Points b1 = point_on_circle( base_radius, base1 ) p1 = point_on_circle( pitch_radius, pitch1 ) o1 = point_on_circle( outer_radius, outer1 ) b2 = point_on_circle( base_radius, base2 ) p2 = point_on_circle( pitch_radius, pitch2 ) o2 = point_on_circle( outer_radius, outer2 ) if root_radius > base_radius: pitch_to_root_angle = pitch_to_base_angle - involute_intersect_angle(base_radius, root_radius ) root1 = pitch1 - pitch_to_root_angle root2 = pitch2 + pitch_to_root_angle r1 = point_on_circle(root_radius, root1) r2 = point_on_circle(root_radius, root2) p_tmp = [r1,p1,o1,o2,p2,r2] else: r1 = point_on_circle(root_radius, base1) r2 = point_on_circle(root_radius, base2) p_tmp = [r1,b1,p1,o1,o2,p2,b2,r2] points.extend( p_tmp ) path = points_to_svgd( points ) # Embed gear in group to make animation easier: # Translate group, Rotate path. view_center = computePointInNode(list(self.view_center), self.current_layer) t = 'translate(' + str( view_center[0] ) + ',' + str( view_center[1] ) + ')' g_attribs = {inkex.addNS('label','inkscape'):'Gear' + str( teeth ), 'transform':t } g = inkex.etree.SubElement(self.current_layer, 'g', g_attribs) # Create SVG Path for gear style = { 'stroke': '#000000', 'fill': 'none', 'stroke-width': str(self.unittouu('1px')) } gear_attribs = {'style':simplestyle.formatStyle(style), 'd':path} gear = inkex.etree.SubElement(g, inkex.addNS('path','svg'), gear_attribs ) if(centerdiameter > 0.0): center_attribs = {'style':simplestyle.formatStyle(style), inkex.addNS('cx','sodipodi') :'0.0', inkex.addNS('cy','sodipodi') :'0.0', inkex.addNS('rx','sodipodi') :str(centerdiameter/2), inkex.addNS('ry','sodipodi') :str(centerdiameter/2), inkex.addNS('type','sodipodi') :'arc' } center = inkex.etree.SubElement(g, inkex.addNS('path','svg'), center_attribs )
def effect(self): OutputGenerated = False # Embed text in group to make manipulation easier: g_attribs = {inkex.addNS('label', 'inkscape'): 'Hershey Text'} g = inkex.etree.SubElement(self.current_layer, 'g', g_attribs) scale = self.unittouu('1px') # convert to document units font = eval('hersheydata.' + str(self.options.fontface)) clearfont = hersheydata.futural #Baseline: modernized roman simplex from JHF distribution. w = 0 #Initial spacing offset v = 0 #Initial vertical offset spacing = 3 # spacing between letters if self.options.action == "render": #evaluate text string letterVals = [ord(q) - 32 for q in self.options.text] for q in letterVals: if (q <= 0) or (q > 95): w += 2 * spacing else: w = draw_svg_text(q, font, w, 0, g) OutputGenerated = True elif self.options.action == 'sample': w, v = self.render_table_of_all_fonts('group_allfonts', g, spacing, clearfont) OutputGenerated = True scale *= 0.4 #Typically scales to about A4/US Letter size else: #Generate glyph table wmax = 0 for p in range(0, 10): w = 0 v = spacing * (15 * p - 67) for q in range(0, 10): r = p * 10 + q if (r <= 0) or (r > 95): w += 5 * spacing else: w = draw_svg_text(r, clearfont, w, v, g) w = draw_svg_text(r, font, w, v, g) w += 5 * spacing if w > wmax: wmax = w w = wmax OutputGenerated = True # Translate group to center of view, approximately view_center = computePointInNode(list(self.view_center), self.current_layer) t = 'translate(' + str(view_center[0] - scale * w / 2) + ',' + str(view_center[1] - scale * v / 2) + ')' if scale != 1: t += ' scale(' + str(scale) + ')' g.set('transform', t) if not OutputGenerated: self.current_layer.remove( g) #remove empty group, if no SVG was generated.
def effect(self): self.options.dx = self.unittouu(str(self.options.dx) + 'px') self.options.divs_th = self.unittouu(str(self.options.divs_th) + 'px') self.options.subdivs_th = self.unittouu( str(self.options.subdivs_th) + 'px') self.options.subsubdivs_th = self.unittouu( str(self.options.subsubdivs_th) + 'px') self.options.border_th = self.unittouu( str(self.options.border_th) + 'px') #Can't generate a grid too flat #If the Y dimension is smallest than half the X dimension, fix it. if self.options.y_divs < ((self.options.x_divs + 1) / 2): self.options.y_divs = int((self.options.x_divs + 1) / 2) #Find the pixel dimensions of the overall grid xmax = self.options.dx * (2 * self.options.x_divs) ymax = self.options.dx * (2 * self.options.y_divs) / 0.866025 #Embed grid in group #Put in in the centre of the current view view_center = computePointInNode(list(self.view_center), self.current_layer) t = 'translate(' + str( view_center[0]- xmax/2.0) + ',' + \ str( view_center[1]- ymax/2.0) + ')' g_attribs = {inkex.addNS('label','inkscape'):'Grid_Polar:X' + \ str( self.options.x_divs )+':Y'+str( self.options.y_divs ), 'transform':t } grid = inkex.etree.SubElement(self.current_layer, 'g', g_attribs) #Group for major x gridlines g_attribs = {inkex.addNS('label', 'inkscape'): 'MajorXGridlines'} majglx = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for major y gridlines g_attribs = {inkex.addNS('label', 'inkscape'): 'MajorYGridlines'} majgly = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for major z gridlines g_attribs = {inkex.addNS('label', 'inkscape'): 'MajorZGridlines'} majglz = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for minor x gridlines if self.options.subdivs > 1: #if there are any minor x gridlines g_attribs = {inkex.addNS('label', 'inkscape'): 'MinorXGridlines'} minglx = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for subminor x gridlines if self.options.subsubdivs > 1: #if there are any minor minor x gridlines g_attribs = { inkex.addNS('label', 'inkscape'): 'SubMinorXGridlines' } mminglx = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for minor y gridlines if self.options.subdivs > 1: #if there are any minor y gridlines g_attribs = {inkex.addNS('label', 'inkscape'): 'MinorYGridlines'} mingly = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for subminor y gridlines if self.options.subsubdivs > 1: #if there are any minor minor x gridlines g_attribs = { inkex.addNS('label', 'inkscape'): 'SubMinorYGridlines' } mmingly = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for minor z gridlines if self.options.subdivs > 1: #if there are any minor y gridlines g_attribs = {inkex.addNS('label', 'inkscape'): 'MinorZGridlines'} minglz = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for subminor z gridlines if self.options.subsubdivs > 1: #if there are any minor minor x gridlines g_attribs = { inkex.addNS('label', 'inkscape'): 'SubMinorZGridlines' } mminglz = inkex.etree.SubElement(grid, 'g', g_attribs) draw_SVG_rect(0, 0, xmax, ymax, self.options.border_th, 'none', 'Border', grid) #Border of grid #X DIVISION #Shortcuts for divisions sd = self.options.subdivs ssd = self.options.subsubdivs #Initializing variable cpt_div = 0 cpt_subdiv = 0 cpt_subsubdiv = 0 com_div = 0 com_subdiv = 0 com_subsubdiv = 0 for i in range(1, (2 * self.options.x_divs * sd * ssd)): cpt_subsubdiv = cpt_subsubdiv + 1 com_subsubdiv = 1 if cpt_subsubdiv == self.options.subsubdivs: cpt_subsubdiv = 0 cpt_subdiv = cpt_subdiv + 1 com_subsubdiv = 0 com_subdiv = 1 com_div = 0 if cpt_subdiv == self.options.subdivs: cpt_subdiv = 0 com_subsubdiv = 0 com_subdiv = 0 com_div = 1 if com_subsubdiv == 1: draw_SVG_line(self.options.dx * i / sd / ssd, 0, self.options.dx * i / sd / ssd, ymax, self.options.subsubdivs_th, 'MajorXDiv' + str(i), mminglx) if com_subdiv == 1: com_subdiv = 0 draw_SVG_line(self.options.dx * i / sd / ssd, 0, self.options.dx * i / sd / ssd, ymax, self.options.subdivs_th, 'MajorXDiv' + str(i), minglx) if com_div == 1: com_div = 0 draw_SVG_line(self.options.dx * i / sd / ssd, 0, self.options.dx * i / sd / ssd, ymax, self.options.divs_th, 'MajorXDiv' + str(i), majglx) #Y DIVISONS #Shortcuts for divisions sd = self.options.subdivs ssd = self.options.subsubdivs taille = self.options.dx / sd / ssd #Size of unity nb_ligne = ( self.options.x_divs + self.options.y_divs ) * self.options.subdivs * self.options.subsubdivs #Global number of lines nb_ligne_x = self.options.x_divs * self.options.subdivs * self.options.subsubdivs #Number of lines X nb_ligne_y = self.options.y_divs * self.options.subdivs * self.options.subsubdivs #Number of lines Y #Initializing variable cpt_div = 0 cpt_subdiv = 0 cpt_subsubdiv = 0 com_div = 0 com_subdiv = 0 com_subsubdiv = 0 for l in range(1, int(nb_ligne * 4)): cpt_subsubdiv = cpt_subsubdiv + 1 com_subsubdiv = 1 if cpt_subsubdiv == self.options.subsubdivs: cpt_subsubdiv = 0 cpt_subdiv = cpt_subdiv + 1 com_subsubdiv = 0 com_subdiv = 1 com_div = 0 if cpt_subdiv == self.options.subdivs: cpt_subdiv = 0 com_subsubdiv = 0 com_subdiv = 0 com_div = 1 if ((2 * l) - 1) < (2 * nb_ligne_x): txa = taille * ((2 * l) - 1) tya = ymax txb = 0 tyb = ymax - (taille) / (2 * 0.866025) - (taille * ((l - 1)) / (0.866025)) if com_subsubdiv == 1: draw_SVG_line(txa, tya, txb, tyb, self.options.subsubdivs_th, 'MajorYDiv' + str(i), mmingly) draw_SVG_line(xmax - txa, tya, xmax - txb, tyb, self.options.subsubdivs_th, 'MajorZDiv' + str(l), mminglz) if com_subdiv == 1: com_subdiv = 0 draw_SVG_line(txa, tya, txb, tyb, self.options.subdivs_th, 'MajorYDiv' + str(i), mingly) draw_SVG_line(xmax - txa, tya, xmax - txb, tyb, self.options.subdivs_th, 'MajorZDiv' + str(l), minglz) if com_div == 1: com_div = 0 draw_SVG_line(txa, tya, txb, tyb, self.options.divs_th, 'MajorYDiv' + str(i), majgly) draw_SVG_line(xmax - txa, tya, xmax - txb, tyb, self.options.divs_th, 'MajorZDiv' + str(l), majglz) if ((2 * l) - 1) == (2 * nb_ligne_x): txa = taille * ((2 * l) - 1) tya = ymax txb = 0 tyb = ymax - (taille) / (2 * 0.866025) - (taille * ((l - 1)) / (0.866025)) if com_subsubdiv == 1: draw_SVG_line(txa, tya, txb, tyb, self.options.subsubdivs_th, 'MajorYDiv' + str(i), mmingly) draw_SVG_line(xmax - txa, tya, xmax - txb, tyb, self.options.subsubdivs_th, 'MajorZDiv' + str(l), mminglz) if com_subdiv == 1: com_subdiv = 0 draw_SVG_line(txa, tya, txb, tyb, self.options.subdivs_th, 'MajorYDiv' + str(i), mingly) draw_SVG_line(xmax - txa, tya, xmax - txb, tyb, self.options.subdivs_th, 'MajorZDiv' + str(l), minglz) if com_div == 1: com_div = 0 draw_SVG_line(txa, tya, txb, tyb, self.options.divs_th, 'MajorYDiv' + str(i), majgly) draw_SVG_line(xmax - txa, tya, xmax - txb, tyb, self.options.divs_th, 'MajorZDiv' + str(l), majglz) if ((2 * l) - 1) > (2 * nb_ligne_x): txa = xmax tya = ymax - (taille) / (2 * 0.866025) - (taille * ((l - 1 - ( (2 * nb_ligne_x) / 2))) / (0.866025)) txb = 0 tyb = ymax - (taille) / (2 * 0.866025) - (taille * ((l - 1)) / (0.866025)) if tyb <= 0: txa = xmax tya = ymax - (taille) / (2 * 0.866025) - (taille * ( (l - 1 - ((2 * nb_ligne_x) / 2))) / (0.866025)) txb = taille * ((2 * (l - (2 * nb_ligne_y)) - 1)) tyb = 0 if txb < xmax: if com_subsubdiv == 1: draw_SVG_line(txa, tya, txb, tyb, self.options.subsubdivs_th, 'MajorYDiv' + str(i), mmingly) draw_SVG_line(xmax - txa, tya, xmax - txb, tyb, self.options.subsubdivs_th, 'MajorZDiv' + str(l), mminglz) if com_subdiv == 1: com_subdiv = 0 draw_SVG_line(txa, tya, txb, tyb, self.options.subdivs_th, 'MajorYDiv' + str(i), mingly) draw_SVG_line(xmax - txa, tya, xmax - txb, tyb, self.options.subdivs_th, 'MajorZDiv' + str(l), minglz) if com_div == 1: com_div = 0 draw_SVG_line(txa, tya, txb, tyb, self.options.divs_th, 'MajorYDiv' + str(i), majgly) draw_SVG_line(xmax - txa, tya, xmax - txb, tyb, self.options.divs_th, 'MajorZDiv' + str(l), majglz) else: if txb < xmax: if com_subsubdiv == 1: draw_SVG_line(txa, tya, txb, tyb, self.options.subsubdivs_th, 'MajorYDiv' + str(i), mmingly) draw_SVG_line(xmax - txa, tya, xmax - txb, tyb, self.options.subsubdivs_th, 'MajorZDiv' + str(l), mminglz) if com_subdiv == 1: com_subdiv = 0 draw_SVG_line(txa, tya, txb, tyb, self.options.subdivs_th, 'MajorYDiv' + str(i), mingly) draw_SVG_line(xmax - txa, tya, xmax - txb, tyb, self.options.subdivs_th, 'MajorZDiv' + str(l), minglz) if com_div == 1: com_div = 0 draw_SVG_line(txa, tya, txb, tyb, self.options.divs_th, 'MajorYDiv' + str(i), majgly) draw_SVG_line(xmax - txa, tya, xmax - txb, tyb, self.options.divs_th, 'MajorZDiv' + str(l), majglz)
def effect(self): so = self.options #PARAMETER PROCESSING if so.NUM_LONG % 2 != 0: #lines of longitude are odd : abort inkex.errormsg(_('Please enter an even number of lines of longitude.')) else: if so.TILT < 0: # if the tilt is backwards flip = ' scale(1, -1)' # apply a vertical flip to the whole sphere else: flip = '' #no flip so.RADIUS = self.unittouu(str(so.RADIUS) + 'px') so.TILT = abs(so.TILT)*(pi/180) #Convert to radians so.ROT_OFFSET = so.ROT_OFFSET*(pi/180) #Convert to radians stroke_width = self.unittouu('1px') EPSILON = 0.001 #add a tiny value to the ellipse radii, so that if we get a zero radius, the ellipse still shows up as a line #INKSCAPE GROUP TO CONTAIN EVERYTHING centre = tuple(computePointInNode(list(self.view_center), self.current_layer)) #Put in in the centre of the current view grp_transform = 'translate' + str( centre ) + flip grp_name = 'WireframeSphere' grp_attribs = {inkex.addNS('label','inkscape'):grp_name, 'transform':grp_transform } grp = inkex.etree.SubElement(self.current_layer, 'g', grp_attribs)#the group to put everything in #LINES OF LONGITUDE if so.NUM_LONG > 0: #only process longitudes if we actually want some #GROUP FOR THE LINES OF LONGITUDE grp_name = 'Lines of Longitude' grp_attribs = {inkex.addNS('label','inkscape'):grp_name} grp_long = inkex.etree.SubElement(grp, 'g', grp_attribs) delta_long = 360.0/so.NUM_LONG #angle between neighbouring lines of longitude in degrees for i in range(0,so.NUM_LONG/2): long_angle = so.ROT_OFFSET + (i*delta_long)*(pi/180.0); #The longitude of this particular line in radians if long_angle > pi: long_angle -= 2*pi width = so.RADIUS * cos(long_angle) height = so.RADIUS * sin(long_angle) * sin(so.TILT) #the rise is scaled by the sine of the tilt # length = sqrt(width*width+height*height) #by pythagorean theorem # inverse = sin(acos(length/so.RADIUS)) inverse = abs(sin(long_angle)) * cos(so.TILT) minorRad = so.RADIUS * inverse minorRad=minorRad + EPSILON #calculate the rotation of the ellipse to get it to pass through the pole (in degrees) rotation = atan(height/width)*(180.0/pi) transform = "rotate("+str(rotation)+')' #generate the transform string #the rotation will be applied about the group centre (the centre of the sphere) # remove the hidden side of the ellipses if required # this is always exactly half the ellipse, but we need to find out which half start_end = (0, 2*pi) #Default start and end angles -> full ellipse if so.HIDE_BACK: if long_angle <= pi/2: #cut out the half ellispse that is hidden start_end = (pi/2, 3*pi/2) else: start_end = (3*pi/2, pi/2) #finally, draw the line of longitude #the centre is always at the centre of the sphere draw_SVG_ellipse( ( minorRad, so.RADIUS ), (0,0), stroke_width, grp_long , start_end,transform) # LINES OF LATITUDE if so.NUM_LAT > 0: #GROUP FOR THE LINES OF LATITUDE grp_name = 'Lines of Latitude' grp_attribs = {inkex.addNS('label','inkscape'):grp_name} grp_lat = inkex.etree.SubElement(grp, 'g', grp_attribs) so.NUM_LAT = so.NUM_LAT + 1 #Account for the fact that we loop over N-1 elements delta_lat = 180.0/so.NUM_LAT #Angle between the line of latitude (subtended at the centre) for i in range(1,so.NUM_LAT): lat_angle=((delta_lat*i)*(pi/180)) #The angle of this line of latitude (from a pole) majorRad=so.RADIUS*sin(lat_angle) #The width of the LoLat (no change due to projection) minorRad=so.RADIUS*sin(lat_angle) * sin(so.TILT) #The projected height of the line of latitude minorRad=minorRad + EPSILON cy=so.RADIUS*cos(lat_angle) * cos(so.TILT) #The projected y position of the LoLat cx=0 #The x position is just the center of the sphere if so.HIDE_BACK: if lat_angle > so.TILT: #this LoLat is partially or fully visible if lat_angle > pi-so.TILT: #this LoLat is fully visible draw_SVG_ellipse((majorRad, minorRad), (cx,cy), stroke_width, grp_lat) else: #this LoLat is partially visible proportion = -(acos( tan(lat_angle - pi/2)/tan(pi/2 - so.TILT)) )/pi + 1 start_end = ( pi/2 - proportion*pi, pi/2 + proportion*pi ) #make the start and end angles (mirror image around pi/2) draw_SVG_ellipse((majorRad, minorRad), (cx,cy), stroke_width, grp_lat, start_end) else: #just draw the full lines of latitude draw_SVG_ellipse((majorRad, minorRad), (cx,cy), stroke_width, grp_lat) #THE HORIZON CIRCLE draw_SVG_ellipse((so.RADIUS, so.RADIUS), (0,0), stroke_width, grp) #circle, centred on the sphere centre
def effect(self): self.options.primaryr = self.unittouu(str(self.options.primaryr) + 'px') self.options.secondaryr = self.unittouu(str(self.options.secondaryr) + 'px') self.options.penr = self.unittouu(str(self.options.penr) + 'px') if self.options.secondaryr == 0: return if self.options.quality == 0: return if(self.options.gearplacement.strip(' ').lower().startswith('outside')): a = self.options.primaryr + self.options.secondaryr flip = -1 else: a = self.options.primaryr - self.options.secondaryr flip = 1 ratio = a / self.options.secondaryr if ratio == 0: return scale = 2 * math.pi / (ratio * self.options.quality) rotation = - math.pi * self.options.rotation / 180; new = inkex.etree.Element(inkex.addNS('path','svg')) s = { 'stroke': '#000000', 'fill': 'none', 'stroke-width': str(self.unittouu('1px')) } new.set('style', simplestyle.formatStyle(s)) pathString = '' maxPointCount = 1000 for i in range(maxPointCount): theta = i * scale view_center = computePointInNode(list(self.view_center), self.current_layer) x = a * math.cos(theta + rotation) + \ self.options.penr * math.cos(ratio * theta + rotation) * flip + \ view_center[0] y = a * math.sin(theta + rotation) - \ self.options.penr * math.sin(ratio * theta + rotation) + \ view_center[1] dx = (-a * math.sin(theta + rotation) - \ ratio * self.options.penr * math.sin(ratio * theta + rotation) * flip) * scale / 3 dy = (a * math.cos(theta + rotation) - \ ratio * self.options.penr * math.cos(ratio * theta + rotation)) * scale / 3 if i <= 0: pathString += 'M ' + str(x) + ',' + str(y) + ' C ' + str(x + dx) + ',' + str(y + dy) + ' ' else: pathString += str(x - dx) + ',' + str(y - dy) + ' ' + str(x) + ',' + str(y) if math.fmod(i / ratio, self.options.quality) == 0 and i % self.options.quality == 0: pathString += 'Z' break else: if i == maxPointCount - 1: pass # we reached the allowed maximum of points, stop here else: pathString += ' C ' + str(x + dx) + ',' + str(y + dy) + ' ' new.set('d', pathString) self.current_layer.append(new)
def effect(self): self.options.dr = self.unittouu(str(self.options.dr) + 'px') self.options.r_divs_th = self.unittouu( str(self.options.r_divs_th) + 'px') self.options.r_subdivs_th = self.unittouu( str(self.options.r_subdivs_th) + 'px') self.options.a_divs_th = self.unittouu( str(self.options.a_divs_th) + 'px') self.options.a_subdivs_th = self.unittouu( str(self.options.a_subdivs_th) + 'px') self.options.c_dot_dia = self.unittouu( str(self.options.c_dot_dia) + 'px') self.options.a_label_size = self.unittouu( str(self.options.a_label_size) + 'px') self.options.a_label_outset = self.unittouu( str(self.options.a_label_outset) + 'px') # Embed grid in group #Put in in the centre of the current view view_center = computePointInNode(list(self.view_center), self.current_layer) t = 'translate(' + str(view_center[0]) + ',' + str( view_center[1]) + ')' g_attribs = { inkex.addNS('label', 'inkscape'): 'Grid_Polar:R' + str(self.options.r_divs) + ':A' + str(self.options.a_divs), 'transform': t } grid = inkex.etree.SubElement(self.current_layer, 'g', g_attribs) dr = self.options.dr #Distance between neighbouring circles dtheta = 2 * pi / self.options.a_divs_cent #Angular change between adjacent radial lines at centre rmax = self.options.r_divs * dr #Create SVG circles for i in range(1, self.options.r_divs + 1): draw_SVG_circle( i * dr, 0, 0, #major div circles self.options.r_divs_th, 'none', 'MajorDivCircle' + str(i) + ':R' + str(i * dr), grid) if self.options.r_log: #logarithmic subdivisions for j in range(2, self.options.r_subdivs): draw_SVG_circle( i * dr - (1 - log(j, self.options.r_subdivs)) * dr, #minor div circles 0, 0, self.options.r_subdivs_th, 'none', 'MinorDivCircle' + str(i) + ':Log' + str(j), grid) else: #linear subdivs for j in range(1, self.options.r_subdivs): draw_SVG_circle( i * dr - j * dr / self.options.r_subdivs, #minor div circles 0, 0, self.options.r_subdivs_th, 'none', 'MinorDivCircle' + str(i) + ':R' + str(i * dr), grid) if self.options.a_divs == self.options.a_divs_cent: #the lines can go from the centre to the edge for i in range(0, self.options.a_divs): draw_SVG_line(0, 0, rmax * sin(i * dtheta), rmax * cos(i * dtheta), self.options.a_divs_th, 'RadialGridline' + str(i), grid) else: #we need separate lines for i in range(0, self.options.a_divs_cent ): #lines that go to the first circle draw_SVG_line(0, 0, dr * sin(i * dtheta), dr * cos(i * dtheta), self.options.a_divs_th, 'RadialGridline' + str(i), grid) dtheta = 2 * pi / self.options.a_divs #work out the angle change for outer lines for i in range(0, self.options.a_divs ): #lines that go from there to the edge draw_SVG_line(dr * sin(i * dtheta + pi / 2.0), dr * cos(i * dtheta + pi / 2.0), rmax * sin(i * dtheta + pi / 2.0), rmax * cos(i * dtheta + pi / 2.0), self.options.a_divs_th, 'RadialGridline' + str(i), grid) if self.options.a_subdivs > 1: #draw angular subdivs for i in range(0, self.options.a_divs): #for each major divison for j in range(1, self.options.a_subdivs): #draw the subdivisions angle = i * dtheta - j * dtheta / self.options.a_subdivs + pi / 2.0 # the angle of the subdivion line draw_SVG_line( dr * self.options.a_subdivs_cent * sin(angle), dr * self.options.a_subdivs_cent * cos(angle), rmax * sin(angle), rmax * cos(angle), self.options.a_subdivs_th, 'RadialMinorGridline' + str(i), grid) if self.options.c_dot_dia <> 0: #if a non-zero diameter, draw the centre dot draw_SVG_circle(self.options.c_dot_dia / 2.0, 0, 0, 0, '#000000', 'CentreDot', grid) if self.options.a_labels == 'deg': label_radius = rmax + self.options.a_label_outset #radius of label centres label_size = self.options.a_label_size numeral_size = 0.73 * label_size #numerals appear to be 0.73 the height of the nominal pixel size of the font in "Sans" for i in range(0, self.options.a_divs ): #self.options.a_divs): #radial line labels draw_SVG_label_centred( sin(i * dtheta + pi / 2.0) * label_radius, #0 at the RHS, mathematical style cos(i * dtheta + pi / 2.0) * label_radius + numeral_size / 2.0, #centre the text vertically str(i * 360 / self.options.a_divs), label_size, 'Label' + str(i), grid)
def effect(self): self.options.border_th = self.unittouu( str(self.options.border_th) + 'px') self.options.dx = self.unittouu(str(self.options.dx) + 'px') self.options.x_divs_th = self.unittouu( str(self.options.x_divs_th) + 'px') self.options.x_subdivs_th = self.unittouu( str(self.options.x_subdivs_th) + 'px') self.options.x_subsubdivs_th = self.unittouu( str(self.options.x_subsubdivs_th) + 'px') self.options.dy = self.unittouu(str(self.options.dy) + 'px') self.options.y_divs_th = self.unittouu( str(self.options.y_divs_th) + 'px') self.options.y_subdivs_th = self.unittouu( str(self.options.y_subdivs_th) + 'px') self.options.y_subsubdivs_th = self.unittouu( str(self.options.y_subsubdivs_th) + 'px') #find the pixel dimensions of the overall grid ymax = self.options.dy * self.options.y_divs xmax = self.options.dx * self.options.x_divs # Embed grid in group #Put in in the centre of the current view view_center = computePointInNode(list(self.view_center), self.current_layer) t = 'translate(' + str( view_center[0]- xmax/2.0) + ',' + \ str( view_center[1]- ymax/2.0) + ')' g_attribs = {inkex.addNS('label','inkscape'):'Grid_Polar:X' + \ str( self.options.x_divs )+':Y'+str( self.options.y_divs ), 'transform':t } grid = inkex.etree.SubElement(self.current_layer, 'g', g_attribs) #Group for major x gridlines g_attribs = {inkex.addNS('label', 'inkscape'): 'MajorXGridlines'} majglx = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for major y gridlines g_attribs = {inkex.addNS('label', 'inkscape'): 'MajorYGridlines'} majgly = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for minor x gridlines if self.options.x_subdivs > 1: #if there are any minor x gridlines g_attribs = {inkex.addNS('label', 'inkscape'): 'MinorXGridlines'} minglx = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for subminor x gridlines if self.options.x_subsubdivs > 1: #if there are any minor minor x gridlines g_attribs = { inkex.addNS('label', 'inkscape'): 'SubMinorXGridlines' } mminglx = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for minor y gridlines if self.options.y_subdivs > 1: #if there are any minor y gridlines g_attribs = {inkex.addNS('label', 'inkscape'): 'MinorYGridlines'} mingly = inkex.etree.SubElement(grid, 'g', g_attribs) #Group for subminor y gridlines if self.options.y_subsubdivs > 1: #if there are any minor minor x gridlines g_attribs = { inkex.addNS('label', 'inkscape'): 'SubMinorYGridlines' } mmingly = inkex.etree.SubElement(grid, 'g', g_attribs) draw_SVG_rect(0, 0, xmax, ymax, self.options.border_th, 'none', 'Border', grid) #border rectangle #DO THE X DIVISONS====================================== sd = self.options.x_subdivs #sub divs per div ssd = self.options.x_subsubdivs #subsubdivs per subdiv for i in range(0, self.options.x_divs): #Major x divisons if i > 0: #dont draw first line (we made a proper border) draw_SVG_line(self.options.dx * i, 0, self.options.dx * i, ymax, self.options.x_divs_th, 'MajorXDiv' + str(i), majglx) if self.options.x_log: #log x subdivs for j in range(1, sd): if j > 1: #the first loop is only for subsubdivs draw_SVG_line(self.options.dx * (i + log(j, sd)), 0, self.options.dx * (i + log(j, sd)), ymax, self.options.x_subdivs_th, 'MinorXDiv' + str(i) + ':' + str(j), minglx) for k in range(1, ssd): #subsub divs if (j <= self.options.x_half_freq) or ( k % 2 == 0 ): #only draw half the subsubdivs past the half-freq point if (ssd % 2 > 0) and ( j > self.options.y_half_freq ): #half frequency won't work with odd numbers of subsubdivs, ssd2 = ssd + 1 #make even else: ssd2 = ssd #no change draw_SVG_line( self.options.dx * (i + log(j + k / float(ssd2), sd)), 0, self.options.dx * (i + log(j + k / float(ssd2), sd)), ymax, self.options.x_subsubdivs_th, 'SubminorXDiv' + str(i) + ':' + str(j) + ':' + str(k), mminglx) else: #linear x subdivs for j in range(0, sd): if j > 0: #not for the first loop (this loop is for the subsubdivs before the first subdiv) draw_SVG_line(self.options.dx * (i + j / float(sd)), 0, self.options.dx * (i + j / float(sd)), ymax, self.options.x_subdivs_th, 'MinorXDiv' + str(i) + ':' + str(j), minglx) for k in range(1, ssd): #subsub divs draw_SVG_line( self.options.dx * (i + (j * ssd + k) / ((float(sd) * ssd))), 0, self.options.dx * (i + (j * ssd + k) / ((float(sd) * ssd))), ymax, self.options.x_subsubdivs_th, 'SubminorXDiv' + str(i) + ':' + str(j) + ':' + str(k), mminglx) #DO THE Y DIVISONS======================================== sd = self.options.y_subdivs #sub divs per div ssd = self.options.y_subsubdivs #subsubdivs per subdiv for i in range(0, self.options.y_divs): #Major y divisons if i > 0: #dont draw first line (we will make a border) draw_SVG_line(0, self.options.dy * i, xmax, self.options.dy * i, self.options.y_divs_th, 'MajorYDiv' + str(i), majgly) if self.options.y_log: #log y subdivs for j in range(1, sd): if j > 1: #the first loop is only for subsubdivs draw_SVG_line(0, self.options.dy * (i + 1 - log(j, sd)), xmax, self.options.dy * (i + 1 - log(j, sd)), self.options.y_subdivs_th, 'MinorXDiv' + str(i) + ':' + str(j), mingly) for k in range(1, ssd): #subsub divs if (j <= self.options.y_half_freq) or ( k % 2 == 0 ): #only draw half the subsubdivs past the half-freq point if (ssd % 2 > 0) and ( j > self.options.y_half_freq ): #half frequency won't work with odd numbers of subsubdivs, ssd2 = ssd + 1 else: ssd2 = ssd #no change draw_SVG_line( 0, self.options.dx * (i + 1 - log(j + k / float(ssd2), sd)), xmax, self.options.dx * (i + 1 - log(j + k / float(ssd2), sd)), self.options.y_subsubdivs_th, 'SubminorXDiv' + str(i) + ':' + str(j) + ':' + str(k), mmingly) else: #linear y subdivs for j in range(0, self.options.y_subdivs): if j > 0: #not for the first loop (this loop is for the subsubdivs before the first subdiv) draw_SVG_line(0, self.options.dy * (i + j / float(sd)), xmax, self.options.dy * (i + j / float(sd)), self.options.y_subdivs_th, 'MinorXYiv' + str(i) + ':' + str(j), mingly) for k in range(1, ssd): #subsub divs draw_SVG_line( 0, self.options.dy * (i + (j * ssd + k) / ((float(sd) * ssd))), xmax, self.options.dy * (i + (j * ssd + k) / ((float(sd) * ssd))), self.options.y_subsubdivs_th, 'SubminorXDiv' + str(i) + ':' + str(j) + ':' + str(k), mmingly)
def effect(self): tri = self.current_layer offset = computePointInNode(list(self.view_center), self.current_layer) #the offset require to centre the triangle self.options.s_a = self.unittouu(str(self.options.s_a) + 'px') self.options.s_b = self.unittouu(str(self.options.s_b) + 'px') self.options.s_c = self.unittouu(str(self.options.s_c) + 'px') stroke_width = self.unittouu('2px') if self.options.mode == '3_sides': s_a = self.options.s_a s_b = self.options.s_b s_c = self.options.s_c draw_tri_from_3_sides(s_a, s_b, s_c, offset, stroke_width, tri) elif self.options.mode == 's_ab_a_c': s_a = self.options.s_a s_b = self.options.s_b a_c = self.options.a_c*pi/180 #in rad s_c = third_side_from_enclosed_angle(s_a,s_b,a_c) draw_tri_from_3_sides(s_a, s_b, s_c, offset, stroke_width, tri) elif self.options.mode == 's_ab_a_a': s_a = self.options.s_a s_b = self.options.s_b a_a = self.options.a_a*pi/180 #in rad if (a_a < pi/2.0) and (s_a < s_b) and (s_a > s_b*sin(a_a) ): #this is an ambigous case ambiguous=True#we will give both answers else: ambiguous=False sin_a_b = s_b*sin(a_a)/s_a if (sin_a_b <= 1) and (sin_a_b >= -1):#check the solution is possible a_b = asin(sin_a_b) #acute solution a_c = pi - a_a - a_b error=False else: sys.stderr.write('Error:Invalid Triangle Specifications.\n')#signal an error error=True if not(error) and (a_b < pi) and (a_c < pi): #check that the solution is valid, if so draw acute solution s_c = third_side_from_enclosed_angle(s_a,s_b,a_c) draw_tri_from_3_sides(s_a, s_b, s_c, offset, stroke_width, tri) if not(error) and ((a_b > pi) or (a_c > pi) or ambiguous):#we want the obtuse solution a_b = pi - a_b a_c = pi - a_a - a_b s_c = third_side_from_enclosed_angle(s_a,s_b,a_c) draw_tri_from_3_sides(s_a, s_b, s_c, offset, stroke_width, tri) elif self.options.mode == 's_a_a_ab': s_a = self.options.s_a a_a = self.options.a_a*pi/180 #in rad a_b = self.options.a_b*pi/180 #in rad a_c = pi - a_a - a_b s_b = s_a*sin(a_b)/sin(a_a) s_c = s_a*sin(a_c)/sin(a_a) draw_tri_from_3_sides(s_a, s_b, s_c, offset, stroke_width, tri) elif self.options.mode == 's_c_a_ab': s_c = self.options.s_c a_a = self.options.a_a*pi/180 #in rad a_b = self.options.a_b*pi/180 #in rad a_c = pi - a_a - a_b s_a = s_c*sin(a_a)/sin(a_c) s_b = s_c*sin(a_b)/sin(a_c) draw_tri_from_3_sides(s_a, s_b, s_c, offset, stroke_width, tri)