import cairo, math colors = [(1,0,0),(0,1,0),(0,0,1),(.8,.2,0),(0,.8,.3)] def ln(x): try: return math.log(x, math.e) except: return None def log(x, base = 10): try: return math.log(x, base) except: return None def sin(x): if Settings["degrees"]: x = math.radians(x) try: return math.sin(x) except: return None def cos(x): if Settings["degrees"]: x = math.radians(x) try: return math.cos(x) except: return None def tan(x): if Settings["degrees"]: x = math.radians(x) try: return math.tan(x) except: return None def csc(x): if Settings["degrees"]: x = math.radians(x) try: return 1.0/math.sin(x) except: return None def sec(x): if Settings["degrees"]: x = math.radians(x) try: return 1.0/math.cos(x) except: return None def cot(x): if Settings["degrees"]: x = math.radians(x) try: return 1.0/math.tan(x) except: return None def sqrt(x): try: return math.sqrt(x) except: return None def calcXpos(x, settings): return float(x - settings["xmin"])/float(settings["xmax"] - settings["xmin"]) * settings["width"] def calcYpos(y, settings): return settings["height"] - float(y - settings["ymin"])/float(settings["ymax"] - settings["ymin"]) * settings["height"] def calcPosFromPolar(r, theta, settings): if settings["degrees"]: theta = math.radians(theta) x = r*math.cos(theta) y = r*math.sin(theta) return (calcXpos(x,settings),calcYpos(y,settings)) class FunctionGraph: def __init__(self, graph, settings, num): self.num = num +1 self.graph = self.formateGraph(graph) self.settings = settings self.color = colors[num] self.points = self.EvaluateGraph() def formateGraph(self, graph): formatedGraph = "" acceptedNumbers = ["1","2","3","4","5","6","7","8","9","0"] acceptedSymbols = [".",",","a","b","c","e","g","i","l","n","o","r","s","t","q","x","*","/","+","-","(",")"] for s in graph: if s in acceptedNumbers: formatedGraph += s if s in acceptedSymbols: formatedGraph += s if s == "{" or s == "[": formatedGraph += ("(") if s == "}" or s == "}": formatedGraph += (")") if s == "^": formatedGraph += ("**") i = 0 while i < len(formatedGraph)-1: if formatedGraph[i] in acceptedNumbers: if formatedGraph[i+1] == "x": i += 1 formatedGraph = formatedGraph[:i] + "*" + formatedGraph[i:] i += 1 return formatedGraph def EvaluateGraph(self): graphList = [] inc = float(self.settings["xmax"]-self.settings["xmin"])/float(self.settings["points"]) x = self.settings["xmin"] while x <= self.settings["xmax"] + inc: y = eval(self.graph) if y != None: graphList.append((calcXpos(x,self.settings),calcYpos(y,self.settings))) x += inc return graphList def draw(self,context): context.set_source_rgb(*self.color) i = 1 context.move_to(*self.points[0]) while i < len(self.points): context.line_to(*self.points[i]) i+=1 context.stroke() class PolarGraph: def __init__(self, graph, settings, num): self.num = num +1 self.graph = self.formateGraph(graph) self.settings = settings self.color = colors[num] self.points = self.EvaluateGraph() def formateGraph(self, graph): formatedGraph = "" acceptedNumbers = ["1","2","3","4","5","6","7","8","9","0"] acceptedSymbols = [".",",","a","b","c","e","g","i","l","n","o","r","s","t","q","x","*","/","+","-","(",")"] for s in graph: if s in acceptedNumbers: formatedGraph += s if s in acceptedSymbols: formatedGraph += s if s == "{" or s == "[": formatedGraph += ("(") if s == "}" or s == "}": formatedGraph += (")") if s == "^": formatedGraph += ("**") i = 0 while i < len(formatedGraph)-1: if formatedGraph[i] in acceptedNumbers: if formatedGraph[i+1] == "x": i += 1 formatedGraph = formatedGraph[:i] + "*" + formatedGraph[i:] i += 1 return formatedGraph def EvaluateGraph(self): graphList = [] inc = float(self.settings["thetamax"]-self.settings["thetamin"])/float(self.settings["points"]) x = self.settings["thetamin"] while x <= self.settings["thetamax"] + inc: y = eval(self.graph) if y != None: graphList.append(calcPosFromPolar(y,x,self.settings)) x += inc return graphList def draw(self,context): context.set_source_rgb(*self.color) i = 1 context.move_to(*self.points[0]) while i < len(self.points): context.line_to(*self.points[i]) i+=1 context.stroke() class ParametricGraph: def __init__(self, graphX, graphY, settings, num): self.num = num +1 self.graphX = self.formateGraph(graphX) self.graphY = self.formateGraph(graphY) self.settings = settings self.color = colors[num] self.points = self.EvaluateGraphs() def formateGraph(self, graph): formatedGraph = "" acceptedNumbers = ["1","2","3","4","5","6","7","8","9","0"] acceptedSymbols = [".","a","b","c","g","i","l","n","o","r","s","t","q","*","/","+","-","(",")"] for s in graph: if s in acceptedNumbers: formatedGraph += s if s in acceptedSymbols: formatedGraph += s if s == "{" or s == "[": formatedGraph += ("(") if s == "}" or s == "}": formatedGraph += (")") if s == "^": formatedGraph += ("**") i = 0 while i < len(formatedGraph)-1: if formatedGraph[i] in acceptedNumbers: if formatedGraph[i+1] == "x": i += 1 formatedGraph = formatedGraph[:i] + "*" + formatedGraph[i:] i += 1 return formatedGraph def EvaluateGraphs(self): graphList = [] inc = float(self.settings["tmax"]-self.settings["tmin"])/float(self.settings["points"]) t = self.settings["tmin"] while t <= self.settings["tmax"] + inc: y = eval(self.graphY) x = eval(self.graphX) graphList.append((calcXpos(x,self.settings),calcYpos(y,self.settings))) t += inc return graphList def draw(self,context): context.set_source_rgb(*self.color) i = 1 context.move_to(*self.points[0]) while i < len(self.points): context.line_to(*self.points[i]) i+=1 context.stroke() class Axis: def __init__(self, settings): global Settings Settings = settings width = settings["width"] height = settings["height"] self.settings = settings self.center = (width - width*(float(settings["xmax"])/(float(settings["xmax"]-settings["xmin"]))), height*(float(settings["ymax"])/(float(settings["ymax"]-settings["ymin"])))) self.x = self.center[0] if self.center[0] < 0: self.x = 0 if self.center[0] > width: self.x = width self.y = self.center[1] if self.center[1] < 0: self.y = 0 if self.center[1] > height: self.y = height def draw(self,context): context.move_to(self.center[0],0) context.line_to(self.center[0],self.settings["height"]) context.stroke() context.move_to(0,self.center[1]) context.line_to(self.settings["width"],self.center[1]) context.stroke() for x in range(int(self.settings["xmin"]), int(self.settings["xmax"])): context.move_to(calcXpos(x, self.settings), self.y-5) context.line_to(calcXpos(x, self.settings), self.y+5) context.stroke() for y in range(int(self.settings["ymin"]), int(self.settings["ymax"])): context.move_to(self.x-5,calcYpos(y, self.settings)) context.line_to(self.x+5,calcYpos(y, self.settings)) context.stroke()