def middle(self): "middle" x = self.xmin + (self.xmax - self.xmin) / _Decimal(2.0) x = Decimal(x, quant=self.quant) y = self.ymin + (self.ymax - self.ymin) / _Decimal(2.0) y = Decimal(y, quant=self.quant) try: z = self.zmin + (self.zmax - self.zmin) / _Decimal(2.0) z = Decimal(z, quant=self.quant) return XY(x, y, z) except AttributeError: return XY(x, y)
def __contains__(self, point): r = point.r if point.r == 0: # dude, whatever r = 0.5 r = Decimal(r, quant=self.line.quant) if r < point.distance(self.xy_max): return True if r < point.distance(self.xy_min): return True line0 = self.translate(self.rise * r, -self.run * r) line1 = self.translate(-self.rise * r, self.run * r) line0 = line0.xy.rotate(self.line.theta, self.line.xy_min) line1 = line0.xy.rotate(self.line.theta, self.line.xy_min) rotator = Affine.rotation2d(self.line.theta, self.line.xy_min) rpoint = point * rotator return between(line0.xy_min.x, rpoint.x, line0.xy_max.x) and \ between(min(line0.xy_min.y, line0.xy_max.y, line1.xy_min.y, line1.xy_max.y), rpoint.y, max(line0.xy_min.y, line0.xy_max.y, line1.xy_min.y, line1.xy_max.y))
def b(self): "the b in 'y = mx + b'" # y = mx + b # y - mx = b # b = y - mx ret = self.ymax - (self.m * self.xmax) return Decimal(ret, quant=self.line.quant)
def distance(self, other): "distance" x = other.x - self.x x *= x x = Decimal(x, quant=self.quant) y = other.y - self.y y *= y y = Decimal(y, quant=self.quant) try: otherz = other.z except AttributeError: otherz = self._z if not self._z: return Decimal(math.sqrt(x + y), quant=self.quant) z2 = otherz z = z2 - self.z z *= z z = Decimal(z, quant=self.quant) return Decimal(math.sqrt(x + y + z), quant=self.quant)
def _inside(val, l, r): val = Decimal(val) if l < r: minimum = l maximum = r else: minimum = r maximum = l if val < minimum - _Decimal(0.01) or val > maximum + _Decimal(0.01): return False return True
def parse(filename): "parse a .obj file" f = open(filename, "r") obj = Model() fonce = True for line in f.readlines(): if line[0] == '#': continue if line.startswith("mtllib "): continue if line.startswith("g "): continue if line.startswith("usemtl "): continue if line.startswith("vt "): continue if line.startswith("vp "): continue if line.startswith("v "): xyz = [x.strip() for x in line.split(' ')[1:]] dxyz = [Decimal(v) for v in xyz] xyz = [float(v) for v in xyz] v = obj.addVertex(dxyz) print("\r%s" % (" " * 79), end='') print("\r%d <= Adding %s" % (v.index, tuple(xyz)), end='') elif line.startswith("f "): if fonce: print("") fonce = False points = [ int(a.split("/")[0].strip()) for a in line.split(" ")[1:] ] print("\r%s" % (" " * 79), end='') print("\rAdding %s" % (tuple(points), ), end='') obj.addFace(*points) print("") return obj
def distance(self, point): "calculate the minimum distance from the line to a point" d = self.xy_min.distance(point) + self.xy_max.distance(point) d = _Decimal(d) / 2 return Decimal(d)
def r(self): "r" return Decimal(self._r, quant=self.quant)
def z(self): "z" if self._z is None: raise AttributeError('z') return Decimal(self._z, quant=self.quant)
def y(self): "y" return Decimal(self._y, quant=self.quant)
def x(self): "x" return Decimal(self._x, quant=self.quant)
def XAtY(self, y): "x at y" # y = mx + b # y -b = mx # (y-b)/m = x return (Decimal(y, quant=self.line.quant) - self.b) / self.m
def YAtX(self, x): "y at x" return self.m * Decimal(x, quant=self.line.quant) + self.b
def __init__(self, x, y, z=None, r=0, quant="10000.000000"): self.quant = quant self._x = Decimal(x, quant=quant) self._y = Decimal(y, quant=quant) self._z = Decimal(z, quant=quant) self._r = Decimal(r, quant=quant)
def m(self): "slope" try: return Decimal(self.rise / self.run, quant=self.line.quant) except decimal.DivisionByZero: return math.inf
def __setstate__(self, state): self.__init__() for vertex in state['vertices']: self.addVertex([Decimal(str(p)) for p in vertex]) for vertices in state['faces']: self.addFace(*vertices)