X-Git-Url: https://svn.cri.ensmp.fr/git/linpy.git/blobdiff_plain/1695c920d030869b3a842736fe5bcf963f2ffc52..843dede1d98c459f9761abff5877e0b019fa0155:/pypol/polyhedra.py?ds=sidebyside diff --git a/pypol/polyhedra.py b/pypol/polyhedra.py index 5d1bfa1..a5d9495 100644 --- a/pypol/polyhedra.py +++ b/pypol/polyhedra.py @@ -5,8 +5,8 @@ import numbers from . import islhelper from .islhelper import mainctx, libisl -from .geometry import GeometricObject, Point, Vector -from .linexprs import Expression, Symbol, Rational +from .geometry import GeometricObject, Point +from .linexprs import Expression, Rational from .domains import Domain @@ -228,142 +228,6 @@ class Polyhedron(Domain): constraints.append(sympy.Ge(inequality.tosympy(), 0)) return sympy.And(*constraints) - @classmethod - def _polygon_inner_point(cls, points): - symbols = points[0].symbols - coordinates = {symbol: 0 for symbol in symbols} - for point in points: - for symbol, coordinate in point.coordinates(): - coordinates[symbol] += coordinate - for symbol in symbols: - coordinates[symbol] /= len(points) - return Point(coordinates) - - @classmethod - def _sort_polygon_2d(cls, points): - if len(points) <= 3: - return points - o = cls._polygon_inner_point(points) - angles = {} - for m in points: - om = Vector(o, m) - dx, dy = (coordinate for symbol, coordinate in om.coordinates()) - angle = math.atan2(dy, dx) - angles[m] = angle - return sorted(points, key=angles.get) - - @classmethod - def _sort_polygon_3d(cls, points): - if len(points) <= 3: - return points - o = cls._polygon_inner_point(points) - a = points[0] - oa = Vector(o, a) - norm_oa = oa.norm() - for b in points[1:]: - ob = Vector(o, b) - u = oa.cross(ob) - if not u.isnull(): - u = u.asunit() - break - else: - raise ValueError('degenerate polygon') - angles = {a: 0.} - for m in points[1:]: - om = Vector(o, m) - normprod = norm_oa * om.norm() - cosinus = max(oa.dot(om) / normprod, -1.) - sinus = u.dot(oa.cross(om)) / normprod - angle = math.acos(cosinus) - angle = math.copysign(angle, sinus) - angles[m] = angle - return sorted(points, key=angles.get) - - def faces(self): - vertices = self.vertices() - faces = [] - for constraint in self.constraints: - face = [] - for vertex in vertices: - if constraint.subs(vertex.coordinates()) == 0: - face.append(vertex) - faces.append(face) - return faces - - def plot(self): - """ - Display 3D plot of set. - """ - import matplotlib.pyplot as plt - import matplotlib.patches as patches - - if len(self.symbols)> 3: - raise TypeError - - elif len(self.symbols) == 2: - import pylab - points = [] - for verts in self.vertices(): - pairs=() - for coordinate, point in verts.coordinates(): - pairs = pairs + (float(point),) - points.append(pairs) - cent=(sum([p[0] for p in points])/len(points),sum([p[1] for p in points])/len(points)) - points.sort(key=lambda p: math.atan2(p[1]-cent[1],p[0]-cent[0])) - pylab.scatter([p[0] for p in points],[p[1] for p in points]) - pylab.gca().add_patch(patches.Polygon(points,closed=True,fill=True)) - pylab.grid() - pylab.show() - - elif len(self.symbols)==3: - from mpl_toolkits.mplot3d import Axes3D - from mpl_toolkits.mplot3d.art3d import Poly3DCollection - faces = self.faces() - fig = plt.figure() - ax = Axes3D(fig) - for face in faces: - points = [] - vertices = Polyhedron._sort_polygon_3d(face) - for verts in vertices: - pairs=() - for coordinate, point in verts.coordinates(): - pairs = pairs + (float(point),) - points.append(pairs) - collection = Poly3DCollection([points], alpha=0.7) - face_color = [0.5, 0.5, 1] # alternative: matplotlib.colors.rgb2hex([0.5, 0.5, 1]) - collection.set_facecolor(face_color) - ax.add_collection3d(collection) - ax.set_xlabel('X') - ax.set_xlim(0, 5) - ax.set_ylabel('Y') - ax.set_ylim(0, 5) - ax.set_zlabel('Z') - ax.set_zlim(0, 5) - plt.grid() - plt.show() - return points - - @classmethod - def limit(cls, faces, variable, lim): - sym = [] - if variable is 'x': - n = 0 - elif variable is 'y': - n = 1 - elif variable is 'z': - n = 2 - for face in faces: - for vert in face: - coordinates = vert.coordinates() - for point in enumerate(coordinates): - coordinates.get(n) - sym.append(points) - if lim == 0: - value = min(sym) - else: - value = max(sym) - return value - def _polymorphic(func): @functools.wraps(func) def wrapper(left, right):