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 createDual(figure, centerPoint=None): if figure.dim<2: raise RuntimeError("Figure has to have at least 2 dimensions") figureElem = sorted(figure, key=attrgetter('dim'), reverse=True)[1:] dualFigure=Figure() for f in figureElem: f.dualCache=None try: for f in figureElem: if not f.dualCache: # create vertex of the dual figure using polar reciprocation vertsPos=[v.position for v in f if v.dim==0] hyperplane=algebra.hyperplaneFromPoints(vertsPos) f.dualCache=Vertex(dualPointFromHyperplane(hyperplane, centerPoint)) for child in f.boundary: if not child.dualCache: child.dualCache=Figure() child.dualCache.addToBoundary(f.dualCache) if child.dim == 0: dualFigure.addToBoundary(child.dualCache) finally: for f in figureElem: del f.dualCache return dualFigure
def cutFigure(wholeFigure, hyperplane): facesAscending=[] queue=[wholeFigure] mark=object() while queue: figure=queue.pop(0) if figure.mark==mark: continue figure.mark=mark facesAscending.insert(0,figure) queue.extend(figure.boundary) for figure in facesAscending: figure.usedInSection=False figure.sectionFacets=[] if figure.dim == 0: # Vertex dist=hyperplane.orientedDistance(figure.position) if abs(dist)<0.0001: figure.cuttingCache=([], [figure], []) elif dist>0: figure.cuttingCache=([], [], [figure]) else: figure.cuttingCache=([figure], [], []) continue; # Edge, face, ... left,middle,right = \ zip(*map(lambda f: f.cuttingCache, figure.boundary)) left,middle,right = (reduce(lambda a,b: a+b, l) for l in (left,middle,right)) if not right and not left: # All in the hyperplane figure.cuttingCache=([], [figure], []) continue if not right or not left: for f in middle: if f.dim==figure.dim-1: for f2 in f.boundary: f2.usedInSection=True figure.sectionFacets.append(f) middle2=[] for f in middle: if not f.usedInSection or f.dim == figure.dim-2: middle2.append(f) middle=middle2 if not right: # Nothing right figure.cuttingCache=([figure], middle, []) continue if not left: # Nothing left figure.cuttingCache=([], middle, [figure]) continue section=[] middle2=set() for f in middle: if f.dim == figure.dim-2: middle2.add(f) elif f.dim != figure.dim-1: section.append(f) middle=middle2 if figure.dim == 1: # Cutting edge diff=algebra.vectDiff(right[0].position, left[0].position) prod=algebra.dotProduct(diff, hyperplane.normal) dist=hyperplane.orientedDistance(left[0].position) vert=Vertex(algebra.vectSum(left[0].position, algebra.vectMult(-dist/prod, diff))) vert.usedInSection=True leftEdge=Figure([left[0], vert]) rightEdge=Figure([right[0], vert]) leftEdge.sectionFacets=[vert] rightEdge.sectionFacets=[vert] figure.cuttingCache=([leftEdge], [vert], [rightEdge]) continue # Cutting face (at least 2-dimensional) leftComp=check.findComponents(left, middle) rightComp=check.findComponents(right, middle) leftComp=[Figure(c) for c in leftComp] rightComp=[Figure(c) for c in rightComp] for rightFigure in rightComp: rightFigure.sectionFacets=[] rightFigure.sectionRidges=set() for f in rightFigure.boundary: rightFigure.sectionRidges.update(f.sectionFacets) for leftFigure in leftComp: leftFigure.sectionFacets=[] leftRidges=set() for f in leftFigure.boundary: leftRidges.update(f.sectionFacets) for rightFigure in rightComp: rightRidges=rightFigure.sectionRidges commonRidges=leftRidges | rightRidges if commonRidges: f=Figure(commonRidges) f.usedInSection=True leftFigure.sectionFacets.append(f) rightFigure.sectionFacets.append(f) leftFigure.boundary.add(f) rightFigure.boundary.add(f) section.append(f) for f in middle: if not f.usedInSection: section.append(f) figure.cuttingCache=(leftComp, section, rightComp) ret=wholeFigure.cuttingCache; for figure in wholeFigure: del figure.cuttingCache del figure.usedInSection return ret;