Оказывается, есть математический алгоритм позволяющий найти координаты точек пересечения 3-х сфер.
Нашел код на Python и адаптировал его для решения моей задачи:
import numpy
from numpy import sqrt, dot, cross
from numpy.linalg import norm
#P1,P2,P3 - координаты центров сфер, r - радиус сфер
def trilaterate(P1,P2,P3,r):
temp1 = P2-P1
e_x = temp1/norm(temp1)
temp2 = P3-P1
i = dot(e_x,temp2)
temp3 = temp2 - i*e_x
e_y = temp3/norm(temp3)
e_z = cross(e_x,e_y)
d = norm(P2-P1)
j = dot(e_y,temp2)
x = (d*d) / (2*d)
y = (-2*i*x + i*i + j*j) / (2*j)
temp4 = r*r - x*x - y*y
if temp4<0:
raise Exception("The three spheres do not intersect!");
z = sqrt(temp4)
p_12_a = P1 + x*e_x + y*e_y + z*e_z
p_12_b = P1 + x*e_x + y*e_y - z*e_z
return p_12_a,p_12_b #возвращаем координаты точек пересечения 3-х сфер
#получаем координаты 3-х выделенных объектов
a = numpy.array(bpy.context.selected_objects[0].location)
b = numpy.array(bpy.context.selected_objects[1].location)
c = numpy.array(bpy.context.selected_objects[2].location)
p = trilaterate(a,b,c,1) #получаем точки пересечения выделенных сфер, r=1
#создаем новую сферу в одной из точек пересечения
bpy.ops.surface.primitive_nurbs_surface_sphere_add(location=p[0])
Выделяем 3 сферы, выполняем этот код и точно на их пересечении появляется 4-я.
У меня все сферы одинакового радиуса, поэтому я упростил функцию trilaterate.
Функция, возвращающая координаты точек пересечения 3-х сфер с произвольными радиусами:
import numpy
from numpy import sqrt, dot, cross
from numpy.linalg import norm
# Find the intersection of three spheres
# P1,P2,P3 are the centers, r1,r2,r3 are the radii
# Implementaton based on Wikipedia Trilateration article.
def trilaterate(P1,P2,P3,r1,r2,r3):
temp1 = P2-P1
e_x = temp1/norm(temp1)
temp2 = P3-P1
i = dot(e_x,temp2)
temp3 = temp2 - i*e_x
e_y = temp3/norm(temp3)
e_z = cross(e_x,e_y)
d = norm(P2-P1)
j = dot(e_y,temp2)
x = (r1*r1 - r2*r2 + d*d) / (2*d)
y = (r1*r1 - r3*r3 -2*i*x + i*i + j*j) / (2*j)
temp4 = r1*r1 - x*x - y*y
if temp4<0:
raise Exception("The three spheres do not intersect!");
z = sqrt(temp4)
p_12_a = P1 + x*e_x + y*e_y + z*e_z
p_12_b = P1 + x*e_x + y*e_y - z*e_z
return p_12_a,p_12_b
ну никак у нескольких сфер или окружностей не может быть единого центра пересечения, если их радиусы меньше или больше расстояния до точки пересечения
Не стал полную цитату приводить :)
Точек пересечения трёх сфер может быть:
- ни одной, если сферы слишком далеко друг от друга, и окружности их попарных пересечений не пересекаются.
- 2, если они достаточно близко к друг другу
- 1 - вырожденный случай, когда 3-я сфера касается окружности пересечения первой и второй сфер (две точки второго случая сливаются в одну)
Случай, когда точек пересечения нет, в коде обработан в строках:
if temp4<0:
raise Exception("The three spheres do not intersect!");