diff --git a/Geometry3D/geometry/plane.py b/Geometry3D/geometry/plane.py index 7b7219c..ef940e8 100644 --- a/Geometry3D/geometry/plane.py +++ b/Geometry3D/geometry/plane.py @@ -6,6 +6,10 @@ from ..utils.solver import solve from ..utils.vector import Vector,x_unit_vector,y_unit_vector,z_unit_vector from ..utils.constant import * + +class InvalidPlane(ValueError): + pass + class Plane(GeoBody): """ - Plane(Point, Point, Point): @@ -63,6 +67,8 @@ def __init__(self, *args): # (the length doesn't matter) so we just use the cross # product vec = vab.cross(vac) + if vec.length() == 0: + raise InvalidPlane('%s x %s == 0' % (vab, vac)) self._init_pn(a, vec) elif len(args) == 2: self._init_pn(*args) diff --git a/Geometry3D/geometry/polygon.py b/Geometry3D/geometry/polygon.py index 7645319..ad2382b 100644 --- a/Geometry3D/geometry/polygon.py +++ b/Geometry3D/geometry/polygon.py @@ -5,12 +5,13 @@ from ..utils.vector import Vector from .line import Line from .segment import Segment -from .plane import Plane +from .plane import Plane, InvalidPlane from ..utils.constant import * from ..utils.vector import x_unit_vector,y_unit_vector import copy import math +from itertools import combinations def get_circle_point_list(center,normal,radius,n=10): if n <= 2: @@ -123,10 +124,14 @@ def __init__(self,pts,reverse = False, check_convex=False): self.points = sorted(set(points),key=points.index) if len(points) < 3: raise ValueError('Cannot build a polygon with number of points smaller than 3') + for triple in combinations(self.points, 3): + try: + self.plane = Plane(*triple) + break + except InvalidPlane as ex: + pass # These 3 points lie on the same line; try the next triple. if reverse: - self.plane = -Plane(self.points[0],self.points[1],self.points[2]) - else: - self.plane = Plane(self.points[0],self.points[1],self.points[2]) + self.plane = -self.plane self.center_point = self._get_center_point()