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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
def calcNormals(pointXyz, triPointDict, pointTriDict):
  '''calculate normals for each point by averaging the adjacent tri normals'''
  triNormals = {}
  for tri in triPointDict.keys():
    points = triPointDict[tri]
    coords = []
    for point in points:
      coords.append(pointXyz[point-1][1:])
    triNormals[tri] = geometry.getTriNormalList(coords)
  outputList = []
  for pointXyzRecord in pointXyz:
    pointNum = pointXyzRecord[0]
    normals = []
    for tri in pointTriDict[pointNum]:
      normals.append(triNormals[tri])
    thisNormal = geometry.getAverage(normals)  # just average the normals
    outputList.append([pointNum, thisNormal[0], thisNormal[1], thisNormal[2]])
  return outputList
Exemplo n.º 4
0
def pca3d(pointList):
  '''sets up the pca for a list of points in 3d. solves eig problem'''
  matrixList = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]  # init to 0
  avgPt = geometry.getAverage(pointList)
  diffs = [0, 0, 0]
  for point in pointList:
    for index in range(3):
      diffs[index] = point[index] - avgPt[index]
    #matrix is old plus a2 ab ac
    #                   ba b2 bc
    #                   ca cb c2 only compute upper diagonal now
    matrixList[0][0] += diffs[0] * diffs[0]  # just hardcode it
    matrixList[0][1] += diffs[0] * diffs[1]
    matrixList[0][2] += diffs[0] * diffs[2]
    matrixList[1][1] += diffs[1] * diffs[1]
    matrixList[1][2] += diffs[1] * diffs[2]
    matrixList[2][2] += diffs[2] * diffs[2]
  #make symmetric
  matrixList[1][0] = matrixList[0][1]
  matrixList[2][0] = matrixList[0][2]
  matrixList[2][1] = matrixList[1][2]
  actualMatrix = Matrix(matrixList)
  val, vec = eigenvectors(actualMatrix)
  return val, vec