2 from __future__
import print_function
3 from builtins
import range
4 from builtins
import object
13 Contains positions of faces and associated vertices 17 """Construct a Dodecahedron 19 @param[in] withFacesOnPoles: if True center a face on each pole, else put a vertex on each pole 27 g = (1.0 + math.sqrt(5.0)) / 2.0
33 unrotFaceVecList = _computeFullVecList(faceBases)
34 unrotVertexVecList = _computeDodecahedronVertices(unrotFaceVecList)
38 vec0, vec1 = _findClosePair(unrotFaceVecList, 0)
39 rotMat = _computeCoordTransform(vec0, vec1)
42 vec0, vec1 = _findClosePair(unrotVertexVecList, 0)
43 rotMat = _computeCoordTransform(vec0, vec1, vec1NegativeX=
True)
44 self.
vertexVecList = [numpy.dot(rotMat, unrotVertexVec)
for unrotVertexVec
in unrotVertexVecList]
45 unsortedFaceList = [numpy.dot(rotMat, unrotFaceVec)
for unrotFaceVec
in unrotFaceVecList]
49 """Return a list of face centers 51 @return a list of face centers (in index order); each a unit vector (numpy array) 56 """Return the center of the specified face 58 @param[in] ind: face index 59 @return face center as a unit vector (numpy array) 64 """Return the vertices for a given face 66 @param[in] ind: face index 67 @return a list of vertices, each a unit vector (numpy array) 70 vertexList, indList = _findCloseList(self.
vertexVecList, faceVec)
73 sortedVertexList = [vertexList[0]]
74 vertexList = list(vertexList[1:])
75 while len(vertexList) != 0:
76 nearVertexList, nearInd = _findCloseList(vertexList, sortedVertexList[-1])
77 sortedVertexList.append(nearVertexList[0])
78 vertexList.pop(nearInd[0])
79 return sortedVertexList
82 """Return the index of the face containing the cartesian vector 84 @param[in] vec: cartesian vector (length is ignored) 85 @return index of face containing vec 87 return numpy.argmax(numpy.dot(self.
faceVecList, vec))
90 """Get withFacesOnPoles parameter 96 """Return a 3D rotation matrix for rotation by a specified amount around a specified axis 99 - angle: amount of rotation (rad) 100 - axis: axis of rotation; one of 0, 1 or 2 for x, y or z 102 cosAng = math.cos(angle)
103 sinAng = math.sin(angle)
104 rotMat = numpy.zeros((3, 3), dtype=float)
105 rotMat[axis, axis] = 1
106 rotMat[(axis + 1) % 3, (axis + 1) % 3] = cosAng
107 rotMat[(axis + 2) % 3, (axis + 1) % 3] = sinAng
108 rotMat[(axis + 1) % 3, (axis + 2) % 3] = -sinAng
109 rotMat[(axis + 2) % 3, (axis + 2) % 3] = cosAng
113 def _computeCoordTransform(vec0, vec1, vec1NegativeX=False):
114 """Compute a rotation matrix that puts vec0 along z and vec1 along +x in the xz plane 119 - vec1NegativeX: if True then vec1 is rotated to face negative x 122 xAng = math.atan2(vec0[1], vec0[2])
126 vec0RotX = numpy.dot(xRotMat, vec0)
127 yAng = -math.atan2(vec0RotX[0], vec0RotX[2])
129 xyRotMat = numpy.dot(yRotMat, xRotMat)
132 vec1RotXY = numpy.dot(xyRotMat, vec1)
136 zAng = -math.atan2(vec1RotXY[1], xVal)
138 xyzRotMat = numpy.dot(zRotMat, xyRotMat)
142 def _computeDodecahedronVertices(faceVecList):
143 """Given a vector of face positions of a Dodecahedron compute the vertices 147 for i
in range(len(faceVecList)):
148 closeIndSet = _findCloseIndexSet(faceVecList, i)
149 if len(closeIndSet) != 5:
150 raise RuntimeError(
"Found %s vertices instead of 5 near %s: %s" %
151 (len(closeIndSet), faceVecList[i], closeIndSet))
152 closeIndSetList.append(closeIndSet)
153 for i, iCloseIndSet
in enumerate(closeIndSetList):
154 for j
in iCloseIndSet:
155 jCloseIndSet = closeIndSetList[j]
156 sharedCloseIndSet = iCloseIndSet.intersection(jCloseIndSet)
157 if len(sharedCloseIndSet) != 2:
158 raise RuntimeError(
"Found %s vertices instead of 2 near %s and %s: %s" %
159 (len(sharedCloseIndSet), faceVecList[i], faceVecList[j], sharedCloseIndSet))
160 for k
in sharedCloseIndSet:
161 key = frozenset((i, j, k))
162 if key
in vertexDict:
164 vertexVec = faceVecList[i] + faceVecList[j] + faceVecList[k]
165 vertexVec /= numpy.sqrt(numpy.sum(vertexVec**2))
166 vertexDict[key] = vertexVec
167 return list(vertexDict.values())
170 def _computeFullVecList(basisSet):
171 """Given a collection of basis vectors, compute all permutations with both signs of all nonzero values 173 For example: [(0, 1, 2)] -> [(0, 1, 2), (0, -1, 2), (0, 1, -2), (0, -1, -2)] 176 for basisVec
in basisSet:
177 vecLen = math.sqrt(numpy.sum(numpy.array(basisVec)**2))
179 for basisValue
in basisVec:
181 valueList.append((0,))
183 valueList.append((basisValue, -basisValue))
184 fullSet += list(numpy.array((x, y, z))/vecLen
185 for z
in valueList[2]
186 for y
in valueList[1]
187 for x
in valueList[0]
192 def _findCloseIndexSet(vecList, ind):
193 """Given a list of cartesian vectors, return a set of indices of those closest to one of them 195 This is intended for regular grids where distances are quantized 198 - vecList: list of cartesian vectors 199 - ind: index of vector to be nearest 201 dotProductList = numpy.round(numpy.dot(vecList, vecList[ind]), 2)
202 dotProductList[ind] = -9e99
203 minDist = numpy.max(dotProductList)
204 indList = numpy.arange(len(dotProductList))[dotProductList == minDist]
208 def _findCloseList(vecList, vec):
209 """Given a list of cartesian vectors, return all those closest to a specified position 211 This is intended for regular grids where distances are quantized 214 - vecList: list of cartesian vectors 215 - vec: vector to be near 218 - list of closest vectors 219 - list if indices of those vectors 221 dotProductList = numpy.round(numpy.dot(vecList, vec), 2)
222 minDist = numpy.max(dotProductList)
223 indList = numpy.arange(len(dotProductList))[dotProductList == minDist]
224 retList = numpy.take(vecList, indList, 0)
225 return retList, indList
228 def _findClosePair(vecList, ind=0):
229 """Given a list of cartesian vectors and an index, return the vector and one of its closest neighbors 232 - vecList: list of cartesian vectors 233 - ind: index of first vector 236 otherVecList = vecList[0:ind] + vecList[ind+1:]
237 ind1 = numpy.argmax(numpy.dot(otherVecList, vec))
238 return vec, otherVecList[ind1]
241 def _sortedVectorList(vecList):
242 """Return a list of cartesian vectors sorted by decreasing latitude and increasing longitude 245 ang = round(math.atan2(vec[1], vec[0]), 2)
248 return (-round(vec[2], 1), ang, vec)
250 decoratedList = [vecToSort(v)
for v
in vecList]
252 return [d[2]
for d
in decoratedList]
254 if __name__ ==
"__main__":
255 numpy.set_printoptions(precision=2, suppress=
True, linewidth=120)
256 import lsst.afw.coord
as afwCoord
257 import lsst.afw.geom
as afwGeom
259 print(
"Dodecahedron with vertices on poles")
262 faceVec = vertexDodec.getFaceCtr(i)
263 print(
"Face %2d: %s" % (i, faceVec))
def computeRotationMatrix(angle, axis)
def getFaceInd(self, vec)
def getFaceCtr(self, ind)
def getVertices(self, ind)
def __init__(self, withFacesOnPoles=False)
def getWithFacesOnPoles(self)