本文整理汇总了Python中qad_utils.getPolarPointByPtAngle函数的典型用法代码示例。如果您正苦于以下问题:Python getPolarPointByPtAngle函数的具体用法?Python getPolarPointByPtAngle怎么用?Python getPolarPointByPtAngle使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了getPolarPointByPtAngle函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: fromStartEndPtsTan
def fromStartEndPtsTan(self, startPt, endPt, tan):
"""
setta le caratteristiche dell'arco attraverso:
punto iniziale
punto finale
direzione della tangente sul punto iniziale
"""
if startPt == endPt:
return False
angleSegment = qad_utils.getAngleBy2Pts(startPt, endPt)
if tan == angleSegment or tan == angleSegment - math.pi:
return False
chord = qad_utils.getDistance(startPt, endPt)
half_chord = chord / 2
ptMiddle = qad_utils.getMiddlePoint(startPt, endPt)
angle = tan + (math.pi / 2)
angle = angleSegment - angle
distFromCenter = math.tan(angle) * half_chord
self.center = qad_utils.getPolarPointByPtAngle(ptMiddle, angleSegment - (math.pi / 2), distFromCenter)
pt = qad_utils.getPolarPointByPtAngle(startPt, tan, chord)
if qad_utils.leftOfLine(endPt, startPt, pt) < 0:
# arco si sviluppa a sinistra della tangente
self.startAngle = qad_utils.getAngleBy2Pts(self.center, startPt)
self.endAngle = qad_utils.getAngleBy2Pts(self.center, endPt)
else:
# arco si sviluppa a destra della tangente
self.startAngle = qad_utils.getAngleBy2Pts(self.center, endPt)
self.endAngle = qad_utils.getAngleBy2Pts(self.center, startPt)
self.radius = qad_utils.getDistance(startPt, self.center)
return True
示例2: fromStartEndPtsAngle
def fromStartEndPtsAngle(self, startPt, endPt, angle):
"""
setta le caratteristiche dell'arco attraverso:
punto iniziale
punto finale
angolo inscritto
"""
if startPt == endPt or angle == 0:
return False
chord = qad_utils.getDistance(startPt, endPt)
half_chord = chord / 2
# Teorema della corda
self.radius = half_chord / math.sin(angle / 2)
angleSegment = qad_utils.getAngleBy2Pts(startPt, endPt)
ptMiddle = qad_utils.getMiddlePoint(startPt, endPt)
# Pitagora
distFromCenter = math.sqrt((self.radius * self.radius) - (half_chord * half_chord))
if angle < math.pi: # se angolo < 180 gradi
# aggiungo 90 gradi per cercare il centro a sinistra del segmento
self.center = qad_utils.getPolarPointByPtAngle(ptMiddle, angleSegment + (math.pi / 2), distFromCenter)
else:
# sottraggo 90 gradi per cercare il centro a destra del segmento
self.center = qad_utils.getPolarPointByPtAngle(ptMiddle, angleSegment - (math.pi / 2), distFromCenter)
self.startAngle = qad_utils.getAngleBy2Pts(self.center, startPt)
self.endAngle = qad_utils.getAngleBy2Pts(self.center, endPt)
return True
示例3: getPerpendicularPoints
def getPerpendicularPoints(self, point):
result = []
angle = qad_utils.getAngleBy2Pts(self.center, point)
if qad_utils.isAngleBetweenAngles(self.startAngle, self.endAngle, angle) == True:
result.append(qad_utils.getPolarPointByPtAngle(self.center, angle, self.radius))
angle = angle + math.pi
if qad_utils.isAngleBetweenAngles(self.startAngle, self.endAngle, angle) == True:
result.append(qad_utils.getPolarPointByPtAngle(self.center, angle, self.radius))
return result
示例4: setLinearDimPtsAndDimLineAlignmentOnCircle
def setLinearDimPtsAndDimLineAlignmentOnCircle(self, LinePosPt, circle):
pt1 = qad_utils.getPolarPointByPtAngle(circle.center, self.forcedDimLineRot, circle.radius)
pt2 = qad_utils.getPolarPointByPtAngle(pt1, self.forcedDimLineRot + math.pi / 2, circle.radius)
horizLine1 = [pt1, pt2]
pt1 = qad_utils.getPolarPointByPtAngle(circle.center, self.forcedDimLineRot, -1 * circle.radius)
pt2 = qad_utils.getPolarPointByPtAngle(pt1, self.forcedDimLineRot + math.pi / 2, circle.radius)
horizLine2 = [pt1, pt2]
pt1 = qad_utils.getPolarPointByPtAngle(circle.center, self.forcedDimLineRot + math.pi / 2, circle.radius)
pt2 = qad_utils.getPolarPointByPtAngle(pt1, self.forcedDimLineRot, circle.radius)
verticalLine1 = [pt1, pt2]
pt1 = qad_utils.getPolarPointByPtAngle(circle.center, self.forcedDimLineRot + math.pi / 2, -1 * circle.radius)
pt2 = qad_utils.getPolarPointByPtAngle(pt1, self.forcedDimLineRot, circle.radius)
verticalLine2 = [pt1, pt2]
# se non é stato impostato un allineamento forzato, lo calcolo in automatico
if self.forcedDimLineAlignment is None:
self.setDimLineAlignment(LinePosPt, horizLine1, horizLine2, verticalLine1, verticalLine2)
else:
self.preferredAlignment = self.forcedDimLineAlignment
if self.preferredAlignment == QadDimStyleAlignmentEnum.HORIZONTAL:
self.dimPt1 = horizLine1[0]
self.dimPt2 = horizLine2[0]
else:
self.dimPt1 = verticalLine1[0]
self.dimPt2 = verticalLine2[0]
示例5: asPolyline
def asPolyline(self, tolerance2ApproxCurve=None, atLeastNSegment=None):
"""
ritorna una lista di punti che definisce l'arco
"""
if tolerance2ApproxCurve is None:
tolerance = QadVariables.get(QadMsg.translate("Environment variables", "TOLERANCE2APPROXCURVE"))
else:
tolerance = tolerance2ApproxCurve
if atLeastNSegment is None:
_atLeastNSegment = QadVariables.get(QadMsg.translate("Environment variables", "ARCMINSEGMENTQTY"), 12)
else:
_atLeastNSegment = atLeastNSegment
# Calcolo la lunghezza del segmento con pitagora
dummy = self.radius - tolerance
if dummy <= 0: # se la tolleranza é troppo bassa rispetto al raggio
SegmentLen = self.radius
else:
dummy = (self.radius * self.radius) - (dummy * dummy)
SegmentLen = math.sqrt(dummy) # radice quadrata
SegmentLen = SegmentLen * 2
if SegmentLen == 0: # se la tolleranza é troppo bassa la lunghezza del segmento diventa zero
return None
# calcolo quanti segmenti ci vogliono (non meno di _atLeastNSegment)
SegmentTot = math.ceil(self.length() / SegmentLen)
if SegmentTot < _atLeastNSegment:
SegmentTot = _atLeastNSegment
points = []
# primo punto
pt = qad_utils.getPolarPointByPtAngle(self.center, self.startAngle, self.radius)
points.append(pt)
i = 1
angle = self.startAngle
offSetAngle = self.totalAngle() / SegmentTot
while i < SegmentTot:
angle = angle + offSetAngle
pt = qad_utils.getPolarPointByPtAngle(self.center, angle, self.radius)
points.append(pt)
i = i + 1
# ultimo punto
pt = qad_utils.getPolarPointByPtAngle(self.center, self.endAngle, self.radius)
points.append(pt)
return points
示例6: fromStartEndPtsRadius
def fromStartEndPtsRadius(self, startPt, endPt, radius):
"""
setta le caratteristiche dell'arco attraverso:
punto iniziale
punto finale
raggio
"""
if startPt == endPt or radius <= 0:
return False
chord = qad_utils.getDistance(startPt, endPt)
half_chord = chord / 2
if radius < half_chord:
return False
self.radius = radius
angleSegment = qad_utils.getAngleBy2Pts(startPt, endPt)
ptMiddle = qad_utils.getMiddlePoint(startPt, endPt)
# Pitagora
distFromCenter = math.sqrt((self.radius * self.radius) - (half_chord * half_chord))
# aggiungo 90 gradi
self.center = qad_utils.getPolarPointByPtAngle(ptMiddle, angleSegment + (math.pi / 2), distFromCenter)
self.startAngle = qad_utils.getAngleBy2Pts(self.center, startPt)
self.endAngle = qad_utils.getAngleBy2Pts(self.center, endPt)
return True
示例7: arrayPolarEntity
def arrayPolarEntity(plugIn, ent, basePt, centerPt, itemsNumber, angleBetween, rows, distanceBetweenRows, itemsRotation, \
addToLayer, highlightObj):
"""
serie polare
ent = entità QAD di cui fare la serie (QadEntity o QadDimEntity)
basePt = punto base in map coordinate (QgsPoint)
centerPt = punto centrale in map coordinate (QgsPoint)
itemsNumber = numero di copie da fare
angleBetween = angolo tra un elemento e l'altro (radianti)
rows = numero di righe
distanceBetweenRows = distanza tra le righe in map coordinate
itemsRotation = True se si vuole ruotare gli elementi intorno al cerchio
addToLayer = se è True aggiunge le nuove entità al layer
highlightObj = se è diverso da None vengono aggiunge le geometrie all'oggetto QadHighlight
"""
g = None
coordTransform = None
f = None
if ent.whatIs() == "ENTITY":
f = ent.getFeature()
# trasformo la geometria nel crs del canvas per lavorare con coordinate piane xy
CRS = qgis.utils.iface.mapCanvas().mapSettings().destinationCrs() # CRS corrente
coordTransform = QgsCoordinateTransform(ent.crs(), CRS)
g = f.geometry()
g.transform(coordTransform)
coordTransform = QgsCoordinateTransform(CRS, ent.crs())
rotFldName = ""
if ent.getEntityType() == QadEntityGeomTypeEnum.TEXT:
# se la rotazione dipende da un solo campo
rotFldNames = qad_label.get_labelRotationFieldNames(ent.layer)
if len(rotFldNames) == 1 and len(rotFldNames[0]) > 0:
rotFldName = rotFldNames[0]
elif ent.getEntityType() == QadEntityGeomTypeEnum.SYMBOL:
rotFldName = qad_layer.get_symbolRotationFieldName(ent.layer)
firstAngle = qad_utils.getAngleBy2Pts(centerPt, basePt)
dist = qad_utils.getDistance(centerPt, basePt)
for row in range(0, rows):
angle = firstAngle
for i in range(0, itemsNumber):
newBasePt = qad_utils.getPolarPointByPtAngle(centerPt, angle, dist)
offSetX = newBasePt.x() - basePt.x()
offSetY = newBasePt.y() - basePt.y()
if g is not None: # se l'entità non è una quotatura
if doMoveAndRotateGeom(plugIn, f, g, ent.layer, offSetX, offSetY, \
i * angleBetween if itemsRotation else None, rotFldName, \
newBasePt, coordTransform, addToLayer, highlightObj) == False:
return False
else: # se l'entità è una quotatura
if doMoveAndRotateDimEntity(plugIn, ent, offSetX, offSetY, \
i * angleBetween if itemsRotation else None, \
newBasePt, addToLayer, highlightObj) == False:
return False
angle = angle + angleBetween
dist = dist + distanceBetweenRows
return True
示例8: canvasMoveEvent
def canvasMoveEvent(self, event):
QadGetPoint.canvasMoveEvent(self, event)
self.__rubberBand.reset()
res = False
# si richiede la selezione dell'oggetto da allungare
if self.mode == Qad_lengthen_maptool_ModeEnum.ASK_FOR_OBJ_TO_LENGTHEN:
if self.tmpEntity.isInitialized():
if self.setInfo(self.tmpEntity, self.tmpPoint) == False:
return
if self.OpMode == "DElta":
if self.OpType == "length":
res = self.tmpLinearObjectList.lengthen_delta(self.move_startPt, self.value)
elif self.OpType == "Angle":
res = self.tmpLinearObjectList.lengthen_deltaAngle(self.move_startPt, self.value)
elif self.OpMode == "Percent":
value = self.tmpLinearObjectList.length() * self.value / 100
value = value - self.tmpLinearObjectList.length()
res = self.tmpLinearObjectList.lengthen_delta(self.move_startPt, value)
elif self.OpMode == "Total":
if self.OpType == "length":
value = self.value - self.tmpLinearObjectList.length()
res = self.tmpLinearObjectList.lengthen_delta(self.move_startPt, value)
elif self.OpType == "Angle":
if self.tmpLinearObjectList.qty() == 1:
linearObject = self.tmpLinearObjectList.getLinearObjectAt(0)
if linearObject.isArc() == True: # se è un arco
value = self.value - linearObject.getArc().totalAngle()
res = self.tmpLinearObjectList.lengthen_deltaAngle(self.move_startPt, value)
# si richiede un punto per la nuova estremità
elif self.mode == Qad_lengthen_maptool_ModeEnum.ASK_FOR_DYNAMIC_POINT:
if self.tmpLinearObjectList.qty() == 1:
transformedPt = self.canvas.mapRenderer().mapToLayerCoordinates(self.layer, self.tmpPoint)
linearObject = self.tmpLinearObjectList.getLinearObjectAt(0)
if linearObject.isSegment():
newPt = qad_utils.getPerpendicularPointOnInfinityLine(linearObject.getStartPt(), linearObject.getEndPt(), transformedPt)
else: # arco
newPt = qad_utils.getPolarPointByPtAngle(linearObject.getArc().center, \
qad_utils.getAngleBy2Pts(linearObject.getArc().center, transformedPt), \
linearObject.getArc().radius)
if self.move_startPt:
linearObject.setStartPt(newPt)
else:
linearObject.setEndPt(newPt)
res = True
if res == False: # allungamento impossibile
return
pts = self.tmpLinearObjectList.asPolyline()
geom = QgsGeometry.fromPolyline(pts)
self.__rubberBand.addGeometry(geom, self.layer)
示例9: setLinearDimLineAlignmentOnDimPts
def setLinearDimLineAlignmentOnDimPts(self, LinePosPt):
# se non é stato impostato un allineamento forzato, lo calcolo in automatico
if self.forcedDimLineAlignment is None:
pt2 = qad_utils.getPolarPointByPtAngle(self.dimPt1, self.forcedDimLineRot + math.pi / 2, 1)
horizLine1 = [self.dimPt1, pt2]
pt2 = qad_utils.getPolarPointByPtAngle(self.dimPt2, self.forcedDimLineRot + math.pi / 2, 1)
horizLine2 = [self.dimPt2, pt2]
pt2 = qad_utils.getPolarPointByPtAngle(self.dimPt1, self.forcedDimLineRot, 1)
verticalLine1 = [self.dimPt1, pt2]
pt2 = qad_utils.getPolarPointByPtAngle(self.dimPt2, self.forcedDimLineRot, 1)
verticalLine2 = [self.dimPt2, pt2]
self.setDimLineAlignment(LinePosPt, horizLine1, horizLine2, verticalLine1, verticalLine2)
else:
self.preferredAlignment = self.forcedDimLineAlignment
示例10: fromStartPtAngleRadiusChordDirection
def fromStartPtAngleRadiusChordDirection(self, startPt, angle, radius, chordDirection):
"""
setta le caratteristiche dell'arco attraverso:
punto iniziale
angolo inscritto
raggio
direzione della corda
"""
if angle == 0 or angle == 2 * math.pi or radius <= 0:
return False
a = chordDirection + (math.pi / 2) - (angle / 2)
self.radius = radius
self.center = qad_utils.getPolarPointByPtAngle(startPt, a, radius)
endPt = qad_utils.getPolarPointByPtAngle(self.center, a + math.pi + angle, radius)
self.startAngle = qad_utils.getAngleBy2Pts(self.center, startPt)
self.endAngle = qad_utils.getAngleBy2Pts(self.center, endPt)
return True
示例11: mirror
def mirror(self, entity, pt1, pt2, rotFldName):
# entity = entità da specchiare
# pt1 e pt2 = linea di simmetria
# rotFldName = campo della tabella che memorizza la rotazione
# verifico se l'entità appartiene ad uno stile di quotatura
if entity.whatIs() == "ENTITY":
f = entity.getFeature()
# specchio l'entità
f.setGeometry(qad_utils.mirrorQgsGeometry(entity.getGeometry(), pt1, pt2))
if len(rotFldName) > 0:
rotValue = f.attribute(rotFldName)
# a volte vale None e a volte null (vai a capire...)
rotValue = 0 if rotValue is None or isinstance(rotValue, QPyNullVariant) else qad_utils.toRadians(rotValue) # la rotazione é in gradi nel campo della feature
ptDummy = qad_utils.getPolarPointByPtAngle(pt1, rotValue, 1)
mirrorAngle = qad_utils.getAngleBy2Pts(pt1, pt2)
ptDummy = qad_utils.mirrorPoint(ptDummy, pt1, mirrorAngle)
rotValue = qad_utils.getAngleBy2Pts(pt1, ptDummy)
f.setAttribute(rotFldName, qad_utils.toDegrees(qad_utils.normalizeAngle(rotValue)))
if self.copyEntities == False:
# plugIn, layer, feature, refresh, check_validity
if qad_layer.updateFeatureToLayer(self.plugIn, entity.layer, f, False, False) == False:
return False
else:
# plugIn, layer, features, coordTransform, refresh, check_validity
if qad_layer.addFeatureToLayer(self.plugIn, entity.layer, f, None, False, False) == False:
return False
elif entity.whatIs() == "DIMENTITY":
mirrorAngle = qad_utils.getAngleBy2Pts(pt1, pt2)
# specchio la quota
if self.copyEntities == False:
if entity.deleteToLayers(self.plugIn) == False:
return False
newDimEntity = QadDimEntity(entity) # la copio
newDimEntity.mirror(pt1, mirrorAngle)
if newDimEntity.addToLayers(self.plugIn) == False:
return False
return True
示例12: getPtFromStart
def getPtFromStart(self, distance):
# la funzione restituisce un punto sull'arco ad una distanza nota da punto iniziale
# (2*pi) : (2*pi*r) = angle : distance
angle = distance / self.radius
angle = self.startAngle + angle
return qad_utils.getPolarPointByPtAngle(self.center, angle, self.radius)
示例13: lengthen
def lengthen(self, point):
layer = self.entity.layer
f = self.entity.getFeature()
if f is None: # non c'è più la feature
return False
geom = self.entity.getGeometry()
# ritorna una tupla (<The squared cartesian distance>,
# <minDistPoint>
# <afterVertex>
# <leftOf>)
res = False
if self.OpMode == "DElta":
newLinearObjectList = qad_utils.QadLinearObjectList(self.linearObjectList)
if self.OpType == "length":
res = newLinearObjectList.lengthen_delta(self.move_startPt, self.value)
elif self.OpType == "Angle":
res = newLinearObjectList.lengthen_deltaAngle(self.move_startPt, self.value)
elif self.OpMode == "Percent":
newLinearObjectList = qad_utils.QadLinearObjectList(self.linearObjectList)
value = newLinearObjectList.length() * self.value / 100
value = value - newLinearObjectList.length()
res = newLinearObjectList.lengthen_delta(self.move_startPt, value)
elif self.OpMode == "Total":
newLinearObjectList = qad_utils.QadLinearObjectList(self.linearObjectList)
if self.OpType == "length":
value = self.value - newLinearObjectList.length()
res = newLinearObjectList.lengthen_delta(self.move_startPt, value)
elif self.OpType == "Angle":
if newLinearObjectList.qty() == 1:
linearObject = newLinearObjectList.getLinearObjectAt(0)
if linearObject.isArc() == True: # se è un arco
value = self.value - linearObject.getArc().totalAngle()
res = newLinearObjectList.lengthen_deltaAngle(self.move_startPt, value)
elif self.OpMode == "DYnamic":
newLinearObjectList = qad_utils.QadLinearObjectList(self.linearObjectList)
transformedPt = self.mapToLayerCoordinates(layer, point)
if self.move_startPt:
linearObject = newLinearObjectList.getLinearObjectAt(0)
else:
linearObject = newLinearObjectList.getLinearObjectAt(-1)
if linearObject.isSegment():
newPt = qad_utils.getPerpendicularPointOnInfinityLine(linearObject.getStartPt(), linearObject.getEndPt(), transformedPt)
else: # arco
newPt = qad_utils.getPolarPointByPtAngle(linearObject.getArc().center, \
qad_utils.getAngleBy2Pts(linearObject.getArc().center, transformedPt), \
linearObject.getArc().radius)
if newLinearObjectList.qty() > 1 and linearObject.isSegment():
ang = linearObject.getTanDirectionOnStartPt()
if self.move_startPt:
linearObject.setStartPt(newPt)
else:
linearObject.setEndPt(newPt)
if newLinearObjectList.qty() > 1 and linearObject.isSegment() and \
qad_utils.TanDirectionNear(ang, linearObject.getTanDirectionOnStartPt()) == False:
res = False
else:
res = True
if res == False: # allungamento impossibile
return False
pts = newLinearObjectList.asPolyline()
updSubGeom = QgsGeometry.fromPolyline(pts)
updGeom = qad_utils.setSubGeom(geom, updSubGeom, self.atSubGeom)
if updGeom is None:
return False
f.setGeometry(updGeom)
self.plugIn.beginEditCommand("Feature edited", layer)
# plugIn, layer, feature, refresh, check_validity
if qad_layer.updateFeatureToLayer(self.plugIn, layer, f, False, False) == False:
self.plugIn.destroyEditCommand()
return False
self.plugIn.endEditCommand()
self.nOperationsToUndo = self.nOperationsToUndo + 1
return True
示例14: arrayRectangleEntity
def arrayRectangleEntity(plugIn, ent, basePt, rows, cols, distanceBetweenRows, distanceBetweenCols, angle, itemsRotation,
addToLayer, highlightObj):
"""
serie rettangolare
ent = entità QAD di cui fare la serie (QadEntity o QadDimEntity)
basePt = punto base in map coordinate (QgsPoint)
rows = numero di righe
cols = numero di colonne
distanceBetweenRows = distanza tra le righe in map coordinate
distanceBetweenCols = distanza tra le colonne in map coordinate
angle = angolo della serie (radianti)
itemsRotation = True se si vuole ruotare gli elementi come l'angolo della serie
addToLayer = se è True aggiunge le nuove entità al layer
highlightObj = se è diverso da None vengono aggiunge le geometrie all'oggetto QadHighlight
la funzione restituisce True in caso di successo e Falso in caso di errore
"""
g = None
coordTransform = None
f = None
if ent.whatIs() == "ENTITY":
f = ent.getFeature()
# trasformo la geometria nel crs del canvas per lavorare con coordinate piane xy
CRS = qgis.utils.iface.mapCanvas().mapSettings().destinationCrs() # CRS corrente
coordTransform = QgsCoordinateTransform(ent.crs(), CRS)
g = f.geometry()
g.transform(coordTransform)
coordTransform = QgsCoordinateTransform(CRS, ent.crs())
rotFldName = ""
if ent.getEntityType() == QadEntityGeomTypeEnum.TEXT:
# se la rotazione dipende da un solo campo
rotFldNames = qad_label.get_labelRotationFieldNames(ent.layer)
if len(rotFldNames) == 1 and len(rotFldNames[0]) > 0:
rotFldName = rotFldNames[0]
elif ent.getEntityType() == QadEntityGeomTypeEnum.SYMBOL:
rotFldName = qad_layer.get_symbolRotationFieldName(ent.layer)
for row in range(0, rows):
firstBasePt = qad_utils.getPolarPointByPtAngle(basePt, angle + math.pi / 2, distanceBetweenRows * row)
distX = 0
for col in range(0, cols):
newBasePt = qad_utils.getPolarPointByPtAngle(firstBasePt, angle, distanceBetweenCols * col)
offSetX = newBasePt.x() - basePt.x()
offSetY = newBasePt.y() - basePt.y()
if g is not None: # se l'entità non è una quotatura
if doMoveAndRotateGeom(plugIn, f, g, ent.layer, offSetX, offSetY, \
angle if itemsRotation else None, rotFldName, \
newBasePt, coordTransform, addToLayer, highlightObj) == False:
return False
else: # se l'entità è una quotatura
if doMoveAndRotateDimEntity(plugIn, ent, offSetX, offSetY, \
angle if itemsRotation else None, \
newBasePt, addToLayer, highlightObj) == False:
return False
distX = distX + distanceBetweenCols
return True
示例15: getMiddlePt
def getMiddlePt(self):
halfAngle = self.totalAngle() / 2
return qad_utils.getPolarPointByPtAngle(self.center, self.startAngle + halfAngle, self.radius)