def detVec(prim, dirVec, exception): global epsilon reload(GeoMath) vec1 = GeoMath.vecNormalize(GeoMath.vecSub(list(prim.vertices()[0].point().position()), list(prim.vertices()[1].point().position()))) vec2 = GeoMath.vecNormalize(GeoMath.vecSub(list(prim.vertices()[2].point().position()), list(prim.vertices()[1].point().position()))) prim_normal = list(prim.normal()) if(list(prim_normal) != [0, 1, 0]): # We consider that y is vertical and x horizontal if(math.fabs(vec1[1]) > math.fabs(vec2[1])): # If the vectors are dependent if(math.fabs(GeoMath.vecDotProduct(vec1, vec2)) > epsilon): vecV = GeoMath.rotateVecByVec(vec2, prim_normal, 90) # Quads!! if(GeoMath.vecDotProduct(vecV, vec1) < -epsilon): vecV = GeoMath.rotateVecByVec(vec2, prim_normal, -90) else: vecV = vec1 vecH = vec2 else: # If the vectors are dependent if(math.fabs(GeoMath.vecDotProduct(vec1, vec2)) > epsilon): vecV = GeoMath.rotateVecByVec(vec1, prim_normal, 90) # Quads!! if(GeoMath.vecDotProduct(vecV, vec2) < -epsilon): vecV = GeoMath.rotateVecByVec(vec1, prim_normal, -90) else: vecV = vec2 vecH = vec1 else: # We consider that x is vertical and z horizontal if(math.fabs(vec1[0]) > math.fabs(vec2[0])): # If the vectors are dependent if(math.fabs(GeoMath.vecDotProduct(vec1, vec2)) > epsilon): vecV = GeoMath.rotateVecByVec(vec2, prim_normal, 90) # Quads!! if(GeoMath.vecDotProduct(vecV, vec1) < -epsilon): vecV = GeoMath.rotateVecByVec(vec2, prim_normal, -90) else: vecV = vec1 vecH = vec2 else: # If the vectors are dependent if(math.fabs(GeoMath.vecDotProduct(vec1, vec2)) > epsilon): vecV = GeoMath.rotateVecByVec(vec1, prim_normal, 90) #Quads!!! if(GeoMath.vecDotProduct(vecV, vec2) < -epsilon): vecV = GeoMath.rotateVecByVec(vec1, prim_normal, -90) else: vecV = vec2 vecH = vec1 if(GeoMath.vecDotProduct(dirVec, vecH) < 0): vecH = GeoMath.vecSub([0, 0, 0], vecH) if(GeoMath.vecDotProduct(dirVec, vecV) < 0): vecV = GeoMath.vecSub([0, 0, 0], vecV) vecH = GeoMath.vecNormalize(vecH) vecV = GeoMath.vecNormalize(vecV) return vecH, vecV
def getSimX(self, pattern): horizontal = abs(GeoMath.vecDotProduct(pattern.getNormal(), [1, 0, 0])) vertical = abs(GeoMath.vecDotProduct(pattern.getNormal(), [0, 1, 0])) oblique = abs(GeoMath.vecDotProduct(pattern.getNormal(), [1, 0, 0])) if (horizontal > vertical and horizontal > oblique): # return vertical simetry, but how this is the x and normal... it will be false return self.simx[1] if(vertical > horizontal and vertical > oblique): # return horizontal return self.simx[0] if(oblique > horizontal and oblique > vertical): # return oblique simetry return self.simx[2]
def getSimNormal(self, pattern): horizontal = abs(GeoMath.vecDotProduct(pattern.getNormal(), [1, 0, 0])) vertical = abs(GeoMath.vecDotProduct(pattern.getNormal(), [0, 1, 0])) oblique = abs(GeoMath.vecDotProduct(pattern.getNormal(), [1, 0, 0])) if (horizontal > vertical and horizontal > oblique): # return vertical simetry return self.simN[1] if(vertical > horizontal and vertical > oblique): # return horizontal simetry return self.simN[0] if(oblique > horizontal and oblique > vertical): # return oblique simetry return self.simN[2]
def getSimX(self, pattern): horizontal = abs(GeoMath.vecDotProduct(pattern.getNormal(), [1, 0, 0])) vertical = abs(GeoMath.vecDotProduct(pattern.getNormal(), [0, 1, 0])) oblique = abs(GeoMath.vecDotProduct(pattern.getNormal(), [1, 0, 0])) if (horizontal > vertical and horizontal > oblique): # return vertical simetry, but how this is the x and normal... it will be false return self.simx[1] if (vertical > horizontal and vertical > oblique): # return horizontal return self.simx[0] if (oblique > horizontal and oblique > vertical): # return oblique simetry return self.simx[2]
def getSimNormal(self, pattern): horizontal = abs(GeoMath.vecDotProduct(pattern.getNormal(), [1, 0, 0])) vertical = abs(GeoMath.vecDotProduct(pattern.getNormal(), [0, 1, 0])) oblique = abs(GeoMath.vecDotProduct(pattern.getNormal(), [1, 0, 0])) if (horizontal > vertical and horizontal > oblique): # return vertical simetry return self.simN[1] if (vertical > horizontal and vertical > oblique): # return horizontal simetry return self.simN[0] if (oblique > horizontal and oblique > vertical): # return oblique simetry return self.simN[2]
def bresenham(Ipoint, point1, fPoint, xSize, ySize, prim, exception): reload (GeoMath) reload (DetermineVectors) reload (Validator) curPoint = point1 dirVec = GeoMath.vecNormalize(GeoMath.vecSub(fPoint, Ipoint)) # Get the horizontal and vertical vectors xVec, yVec = DetermineVectors.DetermineVectors.detVec(prim, dirVec, exception) xSizeVec = GeoMath.vecScalarProduct(xVec, xSize) ySizeVec = GeoMath.vecScalarProduct(yVec, ySize) vecToFinal = GeoMath.vecSub(curPoint, fPoint) sizeToFinalx = abs(GeoMath.vecDotProduct(vecToFinal, xVec) / GeoMath.vecModul(xVec)) sizeToFinaly = abs(GeoMath.vecDotProduct(vecToFinal, yVec) / GeoMath.vecModul(yVec)) if(sizeToFinalx > xSize or sizeToFinaly > ySize): pointx = GeoMath.vecPlus(curPoint, xSizeVec) pointy = GeoMath.vecPlus(curPoint, ySizeVec) pointxy = GeoMath.vecPlus(curPoint, xSizeVec) pointxy = GeoMath.vecPlus(pointxy, ySizeVec) curxVec = GeoMath.vecNormalize(GeoMath.vecSub(pointx, Ipoint)) curyVec = GeoMath.vecNormalize(GeoMath.vecSub(pointy, Ipoint)) curxyVec = GeoMath.vecNormalize(GeoMath.vecSub(pointxy, Ipoint)) # We get the max dot product, the vector nearest to line dotx = GeoMath.vecDotProduct(curxVec, dirVec) doty = GeoMath.vecDotProduct(curyVec, dirVec) dotxy = GeoMath.vecDotProduct(curxyVec, dirVec) pointsTemp = {} if(Validator.Validator.pointInsidePrim(pointx, prim)): pointsTemp[dotx] = pointx if(Validator.Validator.pointInsidePrim(pointy, prim)): pointsTemp[doty] = pointy if(Validator.Validator.pointInsidePrim(pointxy, prim)): pointsTemp[dotxy] = pointxy if(not pointsTemp): point = list(fPoint) else: bestPoint = list(pointsTemp[sorted(pointsTemp)[len(pointsTemp) - 1]]) point = bestPoint else: point = list(fPoint) ''' if(prim.number()==54): print "Ipoint, fpoint" print Ipoint, fPoint print "pointx, pointy, pointxy" print pointx, pointy, pointxy print "Dots" print dotx, doty, dotxy print "sizes" print sizeToFinalx, sizeToFinaly print "Point" print point ''' return point
def applyJoker(self, point1, point2, vecH, vecV): vec = GeoMath.vecSub(point2, point1) dotH = GeoMath.vecDotProduct(vec, vecH) / GeoMath.vecModul(vecH) dotV = GeoMath.vecDotProduct(vec, vecV) / GeoMath.vecModul(vecV) if(math.fabs(dotH) < math.fabs(dotV)): normal = GeoMath.vecNormalize(vecH) else: normal = GeoMath.vecNormalize(vecV) norV = GeoMath.vecNormalize(vecV) norH = GeoMath.vecNormalize(vecH) sizeX = GeoMath.vecModul(GeoMath.vecScalarProduct(norH, dotH)) sizeY = GeoMath.vecModul(GeoMath.vecScalarProduct(norV, dotV)) pointI1 = GeoMath.vecPlus(point1, GeoMath.vecScalarProduct(norH, dotH / 2)) pointI2 = GeoMath.vecPlus(pointI1, GeoMath.vecScalarProduct(norV, dotV)) return WallPattern(normal, [list(point1), pointI1, pointI2, list(point2)], [sizeX, sizeY], 0)
def applyJoker(self, point1, point2, vecH, vecV): vec = GeoMath.vecSub(point2, point1) dotH = GeoMath.vecDotProduct(vec, vecH) / GeoMath.vecModul(vecH) dotV = GeoMath.vecDotProduct(vec, vecV) / GeoMath.vecModul(vecV) if (math.fabs(dotH) < math.fabs(dotV)): normal = GeoMath.vecNormalize(vecH) else: normal = GeoMath.vecNormalize(vecV) norV = GeoMath.vecNormalize(vecV) norH = GeoMath.vecNormalize(vecH) sizeX = GeoMath.vecModul(GeoMath.vecScalarProduct(norH, dotH)) sizeY = GeoMath.vecModul(GeoMath.vecScalarProduct(norV, dotV)) pointI1 = GeoMath.vecPlus(point1, GeoMath.vecScalarProduct(norH, dotH / 2)) pointI2 = GeoMath.vecPlus(pointI1, GeoMath.vecScalarProduct(norV, dotV)) return WallPattern(normal, [list(point1), pointI1, pointI2, list(point2)], [sizeX, sizeY], 0)
def getBestPrimReference(self, curPrim): listPrims = self.totDes index = 0 #More little than the possible dot bestDot = -2 while(index < len(listPrims) and bestDot < 0.998): #Both normals are good, because the projection will be the same dot = GeoMath.vecDotProduct(curPrim.prim.normal(), listPrims[index].prim.normal()) if(dot > bestDot): bestDot = dot bestPrim = listPrims[index] index += 1 return bestPrim
def detVec(prim, dirVec, exception): global epsilon reload(GeoMath) vec1 = GeoMath.vecNormalize( GeoMath.vecSub(list(prim.vertices()[0].point().position()), list(prim.vertices()[1].point().position()))) vec2 = GeoMath.vecNormalize( GeoMath.vecSub(list(prim.vertices()[2].point().position()), list(prim.vertices()[1].point().position()))) prim_normal = list(prim.normal()) if (list(prim_normal) != [0, 1, 0]): # We consider that y is vertical and x horizontal if (math.fabs(vec1[1]) > math.fabs(vec2[1])): # If the vectors are dependent if (math.fabs(GeoMath.vecDotProduct(vec1, vec2)) > epsilon): vecV = GeoMath.rotateVecByVec(vec2, prim_normal, 90) # Quads!! if (GeoMath.vecDotProduct(vecV, vec1) < -epsilon): vecV = GeoMath.rotateVecByVec(vec2, prim_normal, -90) else: vecV = vec1 vecH = vec2 else: # If the vectors are dependent if (math.fabs(GeoMath.vecDotProduct(vec1, vec2)) > epsilon): vecV = GeoMath.rotateVecByVec(vec1, prim_normal, 90) # Quads!! if (GeoMath.vecDotProduct(vecV, vec2) < -epsilon): vecV = GeoMath.rotateVecByVec(vec1, prim_normal, -90) else: vecV = vec2 vecH = vec1 else: # We consider that x is vertical and z horizontal if (math.fabs(vec1[0]) > math.fabs(vec2[0])): # If the vectors are dependent if (math.fabs(GeoMath.vecDotProduct(vec1, vec2)) > epsilon): vecV = GeoMath.rotateVecByVec(vec2, prim_normal, 90) # Quads!! if (GeoMath.vecDotProduct(vecV, vec1) < -epsilon): vecV = GeoMath.rotateVecByVec(vec2, prim_normal, -90) else: vecV = vec1 vecH = vec2 else: # If the vectors are dependent if (math.fabs(GeoMath.vecDotProduct(vec1, vec2)) > epsilon): vecV = GeoMath.rotateVecByVec(vec1, prim_normal, 90) #Quads!!! if (GeoMath.vecDotProduct(vecV, vec2) < -epsilon): vecV = GeoMath.rotateVecByVec(vec1, prim_normal, -90) else: vecV = vec2 vecH = vec1 if (GeoMath.vecDotProduct(dirVec, vecH) < 0): vecH = GeoMath.vecSub([0, 0, 0], vecH) if (GeoMath.vecDotProduct(dirVec, vecV) < 0): vecV = GeoMath.vecSub([0, 0, 0], vecV) vecH = GeoMath.vecNormalize(vecH) vecV = GeoMath.vecNormalize(vecV) return vecH, vecV
def do(self, scale=False): # Calcule points to tbn matrix self.calculatePoints() # Get some arbitrary vectors conected from vertices of prim vec1 = GeoMath.vecSub(self.get_previous_point(), self.get_point_which_is_relative()) vec2 = GeoMath.vecSub(self.get_next_point(), self.get_point_which_is_relative()) # logging.debug('Two arbitrary vec1 and vec2:' + str(vec1) + ' ' + str(vec2)) # We have to know which angle reside between the two coencted vectors, to know if suposed vectors # in tangent space will be correct angle = GeoMath.vecDotProduct(vec1, vec2) / (GeoMath.vecModul(vec1) * GeoMath.vecModul(vec2)) angle = math.acos(angle) angle = math.degrees(angle) # logging.debug('Angle between vecs:' + str(angle)) # We put relative one arbitrary point to tangent space # logging.debug('Point relative:' + str(self.get_point_which_is_relative())) # Determine x and y vectors, now we'll have suposed horizontal and vertical vectors acording to # prim and direction of the crack hasTheNormalToY = GeoMath.vecDotProduct(list(self.get_prim().normal()), [0, 1, 0]) # logging.debug('Has the normal to y?:' + str(hasTheNormalToY)) if(hasTheNormalToY < (1 - epsilon) and hasTheNormalToY > (-1 + epsilon)): vecH, vecV = DetermineVectors.DetermineVectors.detVec(self.get_prim(), [0, 1, 0], [0, 0, 1]) # logging.debug('Yes, it has the normal to y and vecs are:' + str(vecH) + ' ' + str(vecV)) else: vecH, vecV = DetermineVectors.DetermineVectors.detVec(self.get_prim(), [0, 0, 1], [0, 0, 1]) # logging.debug('No, it isnt has the normal to y and vecs are:' + str(vecH) + ' ' + str(vecV)) # CHAPUZA CON NUMEROS COMPLEJOS!!! Precision de python pésima, 1.000000001>1?? no! y math.acos error cosAngle = GeoMath.vecDotProduct(vecH, vec1) / (GeoMath.vecModul(vec1) * GeoMath.vecModul(vecH)) complexAngle = cmath.acos(cosAngle) if(complexAngle.imag == 0): angleBetweenDetVecAndVecH = math.acos(cosAngle) else: if(cosAngle < 0): angleBetweenDetVecAndVecH = math.acos(-1) else: angleBetweenDetVecAndVecH = math.acos(1) # Now we have to ensure that the vec1 has the same direction that the horizontal vector, if not, we # change and the horizontal vector will be vec2. Also we have to check if the prim is not a quad, # in this case we have to get the vertical vector from horizontal vector, rotating the known angle # between the two vectors conected in prim (in quad we know that the angle is 90 and we already have the # good vectors) if((math.fabs(angleBetweenDetVecAndVecH) < epsilon) or (math.fabs(angleBetweenDetVecAndVecH) > (math.pi - epsilon))): if(scale): x = GeoMath.vecScalarProduct([1, 0, 0], GeoMath.vecModul(vec1)) x = [1, 0, 0] y = GeoMath.rotateVecByVec(x, [0, 0, 1], angle) if(scale): y = GeoMath.vecScalarProduct(GeoMath.vecNormalize(y), GeoMath.vecModul(vec2)) tbn = GeoMath.createTBNmatrix(self.get_previous_point(), self.get_point_which_is_relative(), self.get_next_point(), x, [0, 0], y) else: if(scale): x = [1, 0, 0] y = GeoMath.rotateVecByVec(x, [0, 0, 1], angle) if(scale): y = GeoMath.vecScalarProduct(GeoMath.vecNormalize(y), GeoMath.vecModul(vec1)) tbn = GeoMath.createTBNmatrix(self.get_previous_point(), self.get_point_which_is_relative(), self.get_next_point(), y, [0, 0], x) # logging.debug('tbn: ' + str(tbn.printAttributes())) tbnInverse = GeoMath.Matrix(3, 3) tbnInverse.copy(tbn) tbnInverse.matrix3Inverse() self.set_tbn(tbn) self.set_tbn_inverse(tbnInverse)
def defCrack(self, prim, Ipoint, Fpoint, texturePrim): reload(AutoPattern) reload(Bresenham) reload(Data) reload(GeoMath) reload(HouInterface) global epsilon global primnumber # TEMP: only for debug the patterns # Size x and size y is the valor of some material with the minor wavelength(bigger pattern) curPoint = Ipoint self.patternCrack[prim] = [] vertices = [list(p.point().position()) for p in prim.vertices()] print "vertices" print vertices # Convert prim to tangent space of patterns # Get some arbitrary vectors conected from vertices of prim vec1 = GeoMath.vecSub(vertices[0], vertices[1]) vec2 = GeoMath.vecSub(vertices[2], vertices[1]) # We have to know which angle reside between the two coencted vectors, to know if suposed vectors # in tangent space will be correct angle = GeoMath.vecDotProduct(vec1, vec2) / (GeoMath.vecModul(vec1) * GeoMath.vecModul(vec2)) angle = math.acos(angle) angle = math.degrees(angle) # We put relative one arbitrary point to tangent space pointWhichIsRelative = vertices[1] # Determine x and y vectors, now we'll have suposed horizontal and vertical vectors acording to # prim and direction of the crack vecH, vecV = DetermineVectors.DetermineVectors.detVec(prim, GeoMath.vecSub(Ipoint, Fpoint), [0, 0, 1]) # CHAPUZA CON NUMEROS COMPLEJOS!!! Precision de python pésima, 1.000000001>1?? no! y math.acos error cosAngle = GeoMath.vecDotProduct(vecH, vec1) / (GeoMath.vecModul(vec1) * GeoMath.vecModul(vecH)) complexAngle = cmath.acos(cosAngle) if(complexAngle.imag == 0): angleBetweenDetVecAndVecH = math.acos(cosAngle) else: if(cosAngle < 0): angleBetweenDetVecAndVecH = math.acos(-1) else: angleBetweenDetVecAndVecH = math.acos(1) #======================================================================= # Now we have to ensure that the vec1 has the same direction that the horizontal vector, if not, we # change and the horizontal vector will be vec2. Also we have to check if the prim is not a quad, # in this case we have to get the vertical vector from horizontal vector, rotating the known angle # between the two vectors conected in prim (in quad we know that the angle is 90 and we already have the # good vectors) #======================================================================= print "Create TBN" if((math.fabs(angleBetweenDetVecAndVecH) < epsilon) or (math.fabs(angleBetweenDetVecAndVecH) > (math.pi - epsilon))): x = GeoMath.vecScalarProduct([1, 0, 0], GeoMath.vecModul(vec1)) y = GeoMath.rotateVecByVec(x, [0, 0, 1], angle) y = GeoMath.vecScalarProduct(GeoMath.vecNormalize(y), GeoMath.vecModul(vec2)) tbn = GeoMath.createTBNmatrix(vertices[0], vertices[1], vertices[2], x, [0, 0], y) else: x = GeoMath.vecScalarProduct([1, 0, 0], GeoMath.vecModul(vec2)) y = GeoMath.rotateVecByVec(x, [0, 0, 1], angle) y = GeoMath.vecScalarProduct(GeoMath.vecNormalize(y), GeoMath.vecModul(vec1)) tbn = GeoMath.createTBNmatrix(vertices[0], vertices[1], vertices[2], y, [0, 0], x) print "Edn create tbn" tbnInverse = GeoMath.Matrix(3, 3) tbnInverse.copy(tbn) tbnInverse.matrix3Inverse() # Get the first material: print "texture get first layer" texture = texturePrim.getFirstLayer(Ipoint) nextMaterial = texture.get_material() print "end get material" # Create status of the process to show to the user distance_to_complete = GeoMath.vecModul(GeoMath.vecSub(curPoint, Fpoint)) ui_process_status = UIProcessStatus.UIProcessStatus('crack for prim', distance_to_complete) while(GeoMath.vecModul(GeoMath.vecSub(curPoint, Fpoint)) > epsilon): # Print status of the process dist = GeoMath.vecModul(GeoMath.vecSub(curPoint, Fpoint)) ui_process_status.calculate_status(dist, inverse=True) ui_process_status.print_status() genPattern = Data.GeneralPattern() for wavelength in nextMaterial.mat.keys(): singleMat = nextMaterial.mat[wavelength] setOfTypeOfPattern = CDF.cdf([[singleMat.classesAndPercentage[k], k] for k in singleMat.classesAndPercentage.keys()]) if(wavelength == 0): nextPoint = Bresenham.Bresenham.bresenham(Ipoint, curPoint, Fpoint, setOfTypeOfPattern.getSizex(), setOfTypeOfPattern.getSizey(), prim, [1, 0, 0]) pat = AutoPattern.AutoPattern(curPoint, nextPoint, setOfTypeOfPattern, prim, wavelength, self.patternCrack, tbn, tbnInverse, pointWhichIsRelative, texture, texturePrim).pattern genPattern.applyPattern(pat, wavelength) # Check texture previousTexture = texture pii, texture = self.checkTexture(texturePrim, previousTexture, genPattern, Fpoint, nextPoint) logging.debug('Pii defcrack: ' + str(pii)) logging.debug('CurPoint defcrack: ' + str(curPoint)) logging.debug('genPattern ' + str(genPattern.getPoints())) ''' if(not curPoint): curPoint=genPattern.getLastPoint() ''' curPoint = genPattern.getLastPoint() if(texture): nextMaterial = texture.get_material() else: if(not (GeoMath.vecModul(GeoMath.vecSub(curPoint, Fpoint)) > epsilon)): logging.error('Texture no matched, previous texture applied') # version 4 self.patternCrack[prim].append(genPattern)
def do(self): epsilon = 0.001 if (self.DEBUG): print "REF PRIM" print self.refPrim.prim.number() print "########## START PATH ###############" """ Construct a path around refPrim with start prim "firstPrim" and goal prim "lastPrim" if parameter minimum is true, que path is the minimum path, otherwise is the "maximum" path (inverted heuristic, but not maximum path) """ count = 0 path = [] while (not path and count < 2): count += 1 openList = [] closedList = [] connectedPrims = [] if (count == 1): angleMin, angleMax = GeoMath.getMinMaxAngleBetweenPointsInPrim( self.lastPrim.prim, self.firstPrim.prim, self.refPrim.prim) clockWise = max(math.fabs(angleMin), math.fabs(angleMax)) == math.fabs(angleMin) else: clockWise = not clockWise if (self.DEBUG): print "Angulo min max" print angleMin, angleMax, clockWise openList.append(self.firstPrim) # Start A* search while (len(openList) > 0 and (self.lastPrim not in closedList)): # Get the node with more or less heuristic depending of parm minimum if (self.minimum): curPrim = openList[0] del openList[0] else: curPrim = openList.pop() # Switch the current prim to closest list closedList.append(curPrim) # Get connected primitives connectedPrims = GeoMath.getConnectedInfoPrims( curPrim, self.partDes) if (self.DEBUG): print "CLOSE PRIM" print curPrim.prim.number() print "CONNECTED PRIMS" print[conp.prim.number() for conp in connectedPrims] # Clean not possible primitives(because we are go around refPrim) for index in range(len(connectedPrims)): conPrim = connectedPrims[index] # angleMin, angleMax = GeoMath.getMinMaxAngleBetweenPointsInPrim(curPrim.prim, conPrim.prim, refPrim) angleMin = angleMax = GeoMath.angleBetweenPointsByPrim( GeoMath.primBoundingBox(curPrim.prim).center(), GeoMath.primBoundingBox(conPrim.prim).center(), self.refPrim) dot = GeoMath.vecDotProduct(self.refPrim.normal(), conPrim.prim.normal()) if (dot > 1 - epsilon): # precision error dot = 1 # math.acos(dot) > aperture if (self.volume): edges = GeoMath.getEdgesBetweenPrims( curPrim.prim, curPrim.parent.prim) for edge in edges: rs = RejectionSampling.RejectionSampling( edge, self.volume) rs.do() inicialPoint = rs.getValue() if (inicialPoint): break if((not((math.acos(dot) > self.aperture) or \ (clockWise and (angleMin > 0 or angleMin < -(math.pi - math.pi * 0.1))) or \ (not clockWise and (angleMax < 0 or angleMax > (math.pi - math.pi * 0.1))) or \ (conPrim in closedList) or \ (conPrim == self.lastPrim and curPrim.sumAngle < (1.4 * math.pi))) or \ (conPrim == self.lastPrim and curPrim.sumAngle > (1.4 * math.pi))) and \ (inicialPoint or not self.volume)): # If prim is already in openList if (conPrim in openList): heuristic = 1 if ((curPrim.G + heuristic > conPrim.G and not self.minimum) or (curPrim.G + heuristic < conPrim.G and self.minimum)): # If this path is better than the path with the current parent conPrim.setParent(curPrim) conPrim = self.calculateHeuristic( curPrim, conPrim, self.refPrim) if (self.volume): conPrim.fPoint = list(inicialPoint) curPrim.iPoint = list(inicialPoint) if (self.DEBUG): print "Prim aceptada y ya estaba en openlist" print curPrim.prim.number( ), conPrim.prim.number() else: conPrim.setParent(curPrim) conPrim = self.calculateHeuristic( curPrim, conPrim, self.refPrim) if (self.volume): conPrim.fPoint = list(inicialPoint) curPrim.iPoint = list(inicialPoint) openList.append(conPrim) if (self.DEBUG): print "Prim aceptada y no estaba en openlist" print curPrim.prim.number( ), conPrim.prim.number() # Sort nodes by heuristic openList.sort(key=lambda infoPrim: infoPrim.F) if (self.lastPrim in closedList): if (self.DEBUG): print "Last prim Angle", self.lastPrim.sumAngle curPrim = closedList.pop() while (curPrim != self.firstPrim): path.append(curPrim) curPrim = curPrim.parent path.append(curPrim) else: path = [] path.reverse() print "########## FINALIZE PATH ###############" self.path = path
def do(self): epsilon = 0.001 if (self.DEBUG): print "REF PRIM" print self.refPrim.prim.number() print "########## START PATH ###############" """ Construct a path around refPrim with start prim "firstPrim" and goal prim "lastPrim" if parameter minimum is true, que path is the minimum path, otherwise is the "maximum" path (inverted heuristic, but not maximum path) """ count = 0 path = [] while(not path and count < 2): count += 1 openList = [] closedList = [] connectedPrims = [] if(count == 1): angleMin, angleMax = GeoMath.getMinMaxAngleBetweenPointsInPrim(self.lastPrim.prim, self.firstPrim.prim, self.refPrim.prim) clockWise = max(math.fabs(angleMin), math.fabs(angleMax)) == math.fabs(angleMin) else: clockWise = not clockWise if(self.DEBUG): print "Angulo min max" print angleMin, angleMax, clockWise openList.append(self.firstPrim) # Start A* search while(len(openList) > 0 and (self.lastPrim not in closedList)): # Get the node with more or less heuristic depending of parm minimum if(self.minimum): curPrim = openList[0] del openList[0] else: curPrim = openList.pop() # Switch the current prim to closest list closedList.append(curPrim) # Get connected primitives connectedPrims = GeoMath.getConnectedInfoPrims(curPrim, self.partDes) if(self.DEBUG): print "CLOSE PRIM" print curPrim.prim.number() print "CONNECTED PRIMS" print [conp.prim.number() for conp in connectedPrims] # Clean not possible primitives(because we are go around refPrim) for index in range(len(connectedPrims)): conPrim = connectedPrims[index] # angleMin, angleMax = GeoMath.getMinMaxAngleBetweenPointsInPrim(curPrim.prim, conPrim.prim, refPrim) angleMin = angleMax = GeoMath.angleBetweenPointsByPrim(GeoMath.primBoundingBox(curPrim.prim).center(), GeoMath.primBoundingBox(conPrim.prim).center(), self.refPrim) dot = GeoMath.vecDotProduct(self.refPrim.normal(), conPrim.prim.normal()) if(dot > 1 - epsilon): # precision error dot = 1 # math.acos(dot) > aperture if(self.volume): edges = GeoMath.getEdgesBetweenPrims(curPrim.prim, curPrim.parent.prim) for edge in edges: rs = RejectionSampling.RejectionSampling(edge, self.volume) rs.do() inicialPoint = rs.getValue() if(inicialPoint): break if((not((math.acos(dot) > self.aperture) or \ (clockWise and (angleMin > 0 or angleMin < -(math.pi - math.pi * 0.1))) or \ (not clockWise and (angleMax < 0 or angleMax > (math.pi - math.pi * 0.1))) or \ (conPrim in closedList) or \ (conPrim == self.lastPrim and curPrim.sumAngle < (1.4 * math.pi))) or \ (conPrim == self.lastPrim and curPrim.sumAngle > (1.4 * math.pi))) and \ (inicialPoint or not self.volume)): # If prim is already in openList if(conPrim in openList): heuristic = 1 if((curPrim.G + heuristic > conPrim.G and not self.minimum) or (curPrim.G + heuristic < conPrim.G and self.minimum)): # If this path is better than the path with the current parent conPrim.setParent(curPrim) conPrim = self.calculateHeuristic(curPrim, conPrim, self.refPrim) if(self.volume): conPrim.fPoint = list(inicialPoint) curPrim.iPoint = list(inicialPoint) if(self.DEBUG): print "Prim aceptada y ya estaba en openlist" print curPrim.prim.number(), conPrim.prim.number() else: conPrim.setParent(curPrim) conPrim = self.calculateHeuristic(curPrim, conPrim, self.refPrim) if(self.volume): conPrim.fPoint = list(inicialPoint) curPrim.iPoint = list(inicialPoint) openList.append(conPrim) if(self.DEBUG): print "Prim aceptada y no estaba en openlist" print curPrim.prim.number(), conPrim.prim.number() # Sort nodes by heuristic openList.sort(key=lambda infoPrim: infoPrim.F) if(self.lastPrim in closedList): if(self.DEBUG): print "Last prim Angle", self.lastPrim.sumAngle curPrim = closedList.pop() while(curPrim != self.firstPrim): path.append(curPrim) curPrim = curPrim.parent path.append(curPrim) else: path = [] path.reverse() print "########## FINALIZE PATH ###############" self.path = path