def calculateVolume(allTris, triPoints, pointXYZ): '''calculates whole area based on triangles and a random point (0,0,0). individual formula is based on http://mathworld.wolfram.com/Plane.html''' volume = 0.0 areaTotalCheck = 0.0 origin = (0., 0., 0.) # could be any point, but this one is fine for tri in allTris: #calculate volume triPointXYZ = [] # 3 points will be here soon for point in triPoints[tri-1][1:]: triPointXYZ.append(pointXYZ[point-1][1:]) area = geometry.calcTriAreaList(triPointXYZ) normal = geometry.getTriNormalList(triPointXYZ) centerTri = geometry.getAverage(triPointXYZ) planeD = geometry.calculatePlaneD(normal, centerTri) #print triPointXYZ, normal, area height = geometry.planeDistToOrigin(normal+[planeD]) #this height is signed and we can just add it to volume. #volume is 1/3 area * height thisVol = area * height / 3. #print area, normal #print height, thisVol, volume += thisVol areaTotalCheck += area # free to check other computation. #determine whether the point is on the same side as the normal. +/- #can do this but not necessary #side = geometry.checkPlaneSide(normal+[planeD], origin) #if (side and thisVol < 0.) or (not side and thisVol > 0.) or thisVol == 0.: # print side, thisVol if volume > 0.: return volume else: return -volume # since sometimes the origin is inside the shape
def tstEdgeCurvature(trianglePoint, pointXyz, pointTriangle, pointNeighbor): '''for each edge, calculate the angle between the triangles around it. calculate point curvature based on average of these for each point''' triXyz = {} for triPtList in trianglePoint: tri = triPtList[0] xyz = [] for pt in triPtList[1:]: xyz.append(pointXyz[pt-1][1:]) triXyz[tri] = xyz edgeAngle = {} # store edge angles as they are found so don't duplicate work pointMeanAngle = [] # once all edges found, find mean, store in tst format pointWeightedMeanAngle = [] # weight by edge length for pointNeighborList in pointNeighbor: mainPt = pointNeighborList[0] angles = [] weightedAngles = [] for otherPt in pointNeighborList[2:]: # pN[1] is count ptList = [mainPt, otherPt] ptList.sort() ptTuple = tuple(ptList) # canonicalized format edgeLength = geometry.distL2( pointXyz[mainPt-1][1:], pointXyz[otherPt-1][1:]) if ptTuple in edgeAngle: # already done angles.append(edgeAngle[ptTuple]) weightedAngles.append(edgeAngle[ptTuple] * edgeLength) else: # have to compute it mainTris = set(pointTriangle[mainPt-1][2:]) otherTris = set(pointTriangle[otherPt-1][2:]) tris = list(mainTris.intersection(otherTris)) #will almost always be 2 #for now assume only 2 normalA = geometry.getTriNormalList(triXyz[tris[0]]) normalB = geometry.getTriNormalList(triXyz[tris[1]]) unsignedAngle = geometry.getAngle(normalA, normalB) # unsigned centerTriA = geometry.getAverage(triXyz[tris[0]]) planeA = geometry.calculatePlaneD(normalA, centerTriA) ptsB = set(trianglePoint[tris[1]-1][1:]) edgePts = set(ptList) otherB = pointXyz[list(ptsB.difference(edgePts))[0]-1][1:] side = geometry.checkPlaneSide(normalA+[planeA], otherB) if side: angle = - unsignedAngle * 180 / math.pi # concave negative else: angle = unsignedAngle * 180 / math.pi # convex positive edgeAngle[ptTuple] = angle angles.append(angle) weightedAngles.append(angle*edgeLength) pointMeanAngle.append([mainPt, statistics.computeMean(angles)]) pointWeightedMeanAngle.append( [mainPt, statistics.computeMean(weightedAngles)]) return edgeAngle, pointMeanAngle, pointWeightedMeanAngle