diff --git a/GCodeRenderer.py b/GCodeRenderer.py index 9db779a..b0942cd 100644 --- a/GCodeRenderer.py +++ b/GCodeRenderer.py @@ -1,4 +1,5 @@ import cairo, os, math +import Svg2GcodeConverter # This renderer takes the generated GCODE and turns it into two images # One is an SVG of the tool paths, the other a png image @@ -28,8 +29,8 @@ class Renderer(): largest_x = 0 largest_y = 0 - smallest_x = 300 - smallest_y = 300 + smallest_x = 99999999 + smallest_y = 99999999 x = None y = None @@ -78,8 +79,12 @@ class Renderer(): y = None if (prev_x != x and prev_x is not None) or (prev_y != y and prev_y is not None): - self.svg_context.line_to(prev_x, prev_y) - self.svg_context.line_to(x, y) + prev = Svg2GcodeConverter.untriangulate_lengths(self.settings, prev_x, prev_y) + this = Svg2GcodeConverter.untriangulate_lengths(self.settings, x, y) + #self.svg_context.line_to(prev_x, prev_y) + #self.svg_context.line_to(x, y) + self.svg_context.line_to(prev[0], prev[1]) + self.svg_context.line_to(this[0], this[1]) self.svg_context.stroke() print("Largest X : " + str(largest_x)) diff --git a/Svg2GcodeConverter.py b/Svg2GcodeConverter.py index ecde906..5c1db9c 100644 --- a/Svg2GcodeConverter.py +++ b/Svg2GcodeConverter.py @@ -1,7 +1,45 @@ from svgpathtools import svg2paths, Line, QuadraticBezier, CubicBezier import numpy as np -import bezier +import bezier, math +def triangulate_lengths(settings, dest_xy): + + # maybe check for the distance of the move. Split it up into multiple to avoid distortion + + # # get the current length of the left pulley wire + # b = (settings.left_pulley_x_offset + (settings.pulley_diameter/2) + current_xy[0]) + # a = current_xy[1] + settings.pulley_y_droop + # left_line_length = sqrt(pow(a, 2) + pow(b, 2)) + # + # # get the current length of the right pulley wire + # b = (settings.right_pulley_x_offset - (settings.pulley_diameter/2) + current_xy[0]) + # a = current_xy[1] + settings.pulley_y_droop + # right_line_length = sqrt(pow(a, 2) + pow(b, 2)) + + # get the desired length of the left pulley wire + b = (settings.left_pulley_x_offset + (settings.pulley_diameter/2) + dest_xy[0]) + a = dest_xy[1] + settings.pulley_y_droop + desired_left_line_length = math.sqrt(pow(a, 2) + pow(b, 2)) + + # get the desired length of the right pulley wire + b = (settings.right_pulley_x_offset - (settings.pulley_diameter/2) + dest_xy[0]) + a = dest_xy[1] + settings.pulley_y_droop + desired_right_line_length = math.sqrt(pow(a, 2) + pow(b, 2)) + + return desired_left_line_length, desired_right_line_length + + +def untriangulate_lengths(settings, x, y): + result = [0, 0] + + if x > 0: + result[0] = (settings.distance_between_centers * settings.distance_between_centers - y * y + x * x) / (2 * x) + + try: + result[1] = math.sqrt(settings.distance_between_centers * settings.distance_between_centers - result[0] * result[0]) + except: + result[1] = 10 + return result class Svg2GcodeConverter: @@ -15,16 +53,12 @@ class Svg2GcodeConverter: self.gcode_preamble = ''' G91 ; Set to relative mode for the initial pen lift G1 Z1 ; Lift head by 1 - G90 ; Set back to absolute position mode G0 F{1} ; Set the feed rate G1 Z{0} ; Move the pen to just above the paper '''.format(1, self.settings.speed) self.gcode_end = ''' - G1 Z{0} F7000 ; Raise the pen high up so we can fit a cap onto it - M104 S0 ; Set the nozzle to 0 - G28 X0 Y0 ; Home back to (0,0) for (x,y) - M84 ; Turn off the motors + G1 Z{0} F7000 ; Raise the pen '''.format(1) # From an input svg file, convert the vector svg paths to gcode tool paths @@ -76,6 +110,8 @@ class Svg2GcodeConverter: gcode = "" gcode += self.gcode_preamble + current_position = (self.settings.canvas_x/2, self.settings.pulley_y_droop) + # Walk through the paths and create the GCODE for path in paths: @@ -107,7 +143,7 @@ class Svg2GcodeConverter: if lift: gcode += "G1 Z{:.3f}\n".format(1) else: - gcode += ";# NOT LIFTING [{}]\n".format(self.settings.lift_counter) + gcode += "; NOT LIFTING [{}]\n".format(self.settings.lift_counter) if isinstance(part, CubicBezier): @@ -123,18 +159,25 @@ class Svg2GcodeConverter: for i in pos: evals.append(curve.evaluate(i)) - gcode += "G1 X{:.3f} Y{:.3f}\n".format(start_x, start_y) + + #gcode += "G1 X{:.3f} Y{:.3f}\n".format(start_x, start_y) + + lengths = triangulate_lengths(self.settings, (start_x, start_y)) + gcode += "G1 X{:.3f} Y{:.3f}\n".format(lengths[0], lengths[1]) gcode += "G1 Z{:.3f} \n".format(0) for i in evals: x = i[0][0] y = i[1][0] - gcode += "G1 X{:.3f} Y{:.3f}\n".format(x * scale, y * scale) + tmp_len = triangulate_lengths(self.settings, (x * scale, y * scale)) + gcode += "G1 X{:.3f} Y{:.3f}\n".format(tmp_len[0], tmp_len[1]) if isinstance(part, Line): - gcode += "G1 X{:.3f} Y{:.3f}\n".format(start_x, start_y) + start_len = triangulate_lengths(self.settings, (start_x, start_y)) + end_len = triangulate_lengths(self.settings, (end_x, end_y)) + gcode += "G1 X{:.3f} Y{:.3f}\n".format(start_len[0], start_len[1]) gcode += "G1 Z{:.3f} \n".format(0) - gcode += "G1 X{:.3f} Y{:.3f}\n".format(end_x, end_y) + gcode += "G1 X{:.3f} Y{:.3f}\n".format(end_len[0], end_len[1]) gcode += self.gcode_end diff --git a/main.py b/main.py index ce77be5..bcd066a 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,3 @@ -from math import sqrt from tkinter import * from tkinter import filedialog from tkinter.ttk import Notebook @@ -12,23 +11,6 @@ from ImageConverter import ImageConverter from Simulator import Simulator -def xy_to_radial(settings, current_xy, dest_xy, pulley_diameter): - - # maybe check for the distance of the move. Split it up into multiple to avoid distortion - - # get the current length of the left pulley wire - b = (settings.left_pulley_x_offset - settings.pulley_diameter + current_xy[0]) - a = settings.pulley_y_droop - - length = sqrt(pow(a, 2) + pow(b, 2)) - # get the current length of the right pulley wire - - - # get the desired length of the left pulley wire - # get the desired length of the right pulley wire - - return - class Settings: