def hyperplanesOfFigure(figure): hyperplanes = [] vertsPos = [v.position for v in figure if v.dim == 0] innerPoint = algebra.vectAvg(*vertsPos) for facet in figure.boundary: hyperplanes.append(hyperplaneOfFacet(facet, innerPoint)) return hyperplanes
def hyperplanesOfFigure(figure): hyperplanes=[] vertsPos=[v.position for v in figure if v.dim == 0] innerPoint=algebra.vectAvg(*vertsPos) for facet in figure.boundary: hyperplanes.append(hyperplaneOfFacet(facet, innerPoint)) return hyperplanes
def cutOffFaces(figure, ratio, faces): hyperplanes=[] innerPoint=algebra.vectAvg(*[v.position for v in figure if v.dim==0]) for f in faces: points=[v.position for v in f if v.dim==0] basis=algebra.orthonormalBasisFromPoints(points) normal=algebra.orthogonalizeVect(algebra.vectDiff(points[0], innerPoint), basis) if algebra.vectLen(normal)<0.0001: raise RuntimeError("Cannot cut faces") hyperplanes.append(Hyperplane(normal, (1-ratio+algebra.dotProduct(normal, innerPoint)/algebra.vectLen(normal)**2))) return cutOffConvex(figure, hyperplanes, innerPoint)
def isFigureConvex(figure): if not isFigureClosed(figure): return False innerPoint=algebra.vectAvg(*(v.position for v in figure if v.dim==0)) facetsInnerPoints=dict() edgesParents=dict() for facet in figure.boundary: facetsInnerPoints[facet]=algebra.vectAvg(*(v.position for v in facet if v.dim==0)) for edge in facet.boundary: if not edge in edgesParents: edgesParents[edge]=set() edgesParents[edge].add(facet) hyperplanes=spaceCuts.hyperplanesOfFigure(figure); for facet in figure.boundary: hyperplane=spaceCuts.hyperplaneOfFacet(facet, innerPoint) for edge in facet.boundary: facet2=[f for f in edgesParents[edge] if f!=facet][0] point=facetsInnerPoints[facet2] if hyperplane.orientedDistance(point)<0.0001: return False return True
def isFigureConvex(figure): if not isBoundaryComplete(figure): return False innerPoint=algebra.vectAvg(*(v.position for v in figure if v.dim==0)) facetsInnerPoints=dict() edgesParents=dict() for facet in figure.boundary: facetsInnerPoints[facet]=algebra.vectAvg(*(v.position for v in facet if v.dim==0)) for edge in facet.boundary: if not edge in edgesParents: edgesParents[edge]=set() edgesParents[edge].add(facet) hyperplanes=spaceCuts.hyperplanesOfFigure(figure); for facet in figure.boundary: hyperplane=spaceCuts.hyperplaneOfFacet(facet, innerPoint) for edge in facet.boundary: facet2=[f for f in edgesParents[edge] if f!=facet][0] point=facetsInnerPoints[facet2] if hyperplane.orientedDistance(point)<0.0001: return False return True
def stellateFigure(figure): objFigure.updateVerticesLists(figure) objFigure.updateParentsLists(figure) innerPoint=algebra.vectAvg(*[v.position for v in figure.vertices]) for f in figure.boundary: f.hyperplane=spaceCuts.hyperplaneOfFacet(f, innerPoint); f.hyperplane.origFacet=f newFacets=[] for f in figure.boundary: facets=set() for f2 in f.boundary: facets.update(f2.parents) facets.remove(f) hyperplanes=[f2.hyperplane for f2 in facets] hyperplane=f.hyperplane.inverse() hyperplane.origFacet=f apexPoint=algebra.vectAvg(*[v.position for v in f.vertices]) dist=float('inf') for h in hyperplanes: p=algebra.dotProduct(hyperplane.normal, h.normal) if p<-0.0001: d=-h.orientedDistance(apexPoint)/p if d<0.0001: raise RuntimeError("The figure is not convex") elif d<dist: dist=d if dist == float('inf'): raise RuntimeError("Infinite stellations are not supported") hyperplanes.append(hyperplane) apexInnerPoint=algebra.vectSum(apexPoint, algebra.vectMult(dist/2.0, hyperplane.normal)) apexFigure=spaceCuts.figureFromArea(hyperplanes, apexInnerPoint) apexBaseFacet=[f3 for f3 in apexFigure.boundary if f3.origHypp.origFacet==f][0] for f3 in apexFigure: f3.origFace=None apexFigure.rmFromBoundary(apexBaseFacet) for apexFacet in apexFigure.boundary: apexRidge=(apexFacet.boundary & apexBaseFacet.boundary).pop() apexRidge.origFace=(apexFacet.origHypp.origFacet.boundary & f.boundary).pop() objFigure.updateParentsLists(apexBaseFacet) queue=[] for apexRidge in apexBaseFacet.boundary: queue.extend(apexRidge.boundary) while queue: apexFace=queue.pop(0) if apexFace.origFace: continue origP1=apexFace.parents[0].origFace origP2=apexFace.parents[1].origFace apexFace.origFace=(origP1.boundary & origP2.boundary).pop() queue.extend(apexFace.boundary) for f3 in apexBaseFacet: del f3.parents queue=[apexFigure] apexFigure.mark=True while queue: apexFace=queue.pop(0) if not apexFace.mark: continue apexFace.mark=None for apexFace2 in list(apexFace.boundary): if apexFace2.origFace: apexFace.boundary.remove(apexFace2) apexFace.boundary.add(apexFace2.origFace) else: apexFace2.mark=True queue.append(apexFace2) newFacets.extend(apexFigure.boundary) return objFigure.Figure(newFacets)