def createDual(figure, centerPoint=None): if figure.dim<2: raise RuntimeError("Figure has to have at least 2 dimensions") dualFigure=Figure() objFigure.updateVerticesLists(figure) for f in figure: f.dualCache=None try: for f in figure: d=figure.dim-f.dim-1 if d<0: continue if d==0: # create vertex of the dual figure using polar reciprocation vertsPos=[v.position for v in f.vertices] hyperplane=algebra.hyperplaneFromPoints(vertsPos) f.dualCache=Vertex(dualPointFromHyperplane(hyperplane, centerPoint)) else: f.dualCache=Figure() f.dualCache.setDim(d,figure.spaceDim) f.dualCache.origDualFace=f for f in figure: if f.dim<figure.dim: for child in f.boundary: child.dualCache.addToBoundary(f.dualCache) if f.dim == 0: dualFigure.addToBoundary(f.dualCache) finally: for f in figure: del f.dualCache return dualFigure
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)