听起来很有趣!如果您的3个点击点位于同一象限中,则由这些点定义的三角形的一个角度必须是钝角。调用B和其他两个顶点A和C. x-y定向椭圆的一般方程中有4个参数。将A,B和C的x和y坐标代入椭圆方程将给出三个方程。你需要拿出第4个。您可以自由选择在游戏环境中有意义的第四点。这是一个SymPy代码片段,它根据A,B和C以及参数“f”将x值分配给椭圆的中心。
def e3(p1, p2, p3, f):
t = Triangle(p1, p2, p3)
a = t.angles
for p in a:
if a[p] > pi/2:
break
else:
return
while p != p2:
p1, p2, p3 = p2, p3, p1
pts = A, B, C = p1, p2, p3
# perpendicular line to AB passing through A
perp = Segment(A, B).perpendicular_line(A)
# intersection between that and the perpendicular to that
# which passes through C
m = perp.perpendicular_line(C).intersection(perp)[0]
delta = m - A
c = A + delta*f
x, y, h, r, y0 = symbols('x y h r y0', cls=Dummy)
eq = Ellipse((c.x, y0), h, r).equation(x, y)
s = solve([
eq.xreplace(dict(zip((x, y), p))) for p in pts], dict=True)[0]
return eq.subs(s) # for desmos graphing: str(eq.subs(s)).replace('**','^').replace('_','')+'=0'
f = .125,.25,.5,1,2的一些结果显示在desmos。
您可以看到他们都通过您提供的要点作为示例。红色圆圈提供了一个有趣的参考点。您可能想要选择一个f,因此椭圆的最终宽度是圆的直径的一小部分,它将通过这些点。
然而,椭圆经过的点不在每个椭圆的相同象限中。要满足该标准,您必须考虑“离轴”椭圆。使用here发布的任意椭圆方程可能也会有所帮助,以指导您在定义椭圆时选择要控制的变量。
为了使方程尽可能简单地求解和确定,如果该角度产生锐角,则可以使轴穿过第二个点击点,否则通过第1和第3点。这是代码证明:
def e3(A, B, C, n=7):
'''Return centered at the midpoint of A and C with the axis going through B if the angle at B is acute, else going through A and C.
'''
from sympy import Line
xc, yc = ctr = (A + C)/2
AC = A.distance(C)
smalls = True
if AC >= B.distance(A) and AC >= B.distance(C):
s = Line(A, C).slope
M2 = ctr.distance(A)**2
b = B
if abs(s) <= 1:
m2 = -M2*(s*(b.x - xc) - b.y + yc)**2/(
-M2*(s**2 + 1) + (s*(b.y - yc) + b.x - xc)**2)
else:
s = 1/s
m2 = M2*(s*(b.y - yc) - b.x + xc)**2/(
M2*(s**2 + 1) - (s*(b.x - xc) + b.y - yc)**2)
smalls = False
else:
s = Line(B, ctr).slope
M2 = ctr.distance(B)**2
p = A # or C
if abs(s) <= 1:
m2 = -M2*(s*(p.x - xc) - p.y + yc)**2/(
-M2*(s**2 + 1) + (s*(p.y - yc) + p.x - xc)**2)
else:
s = 1/s
m2 = M2*(s*(p.y - yc) - p.x + xc)**2/(
M2*(s**2 + 1) - (s*(p.x - xc) + p.y - yc)**2)
smalls = False
if smalls:
el = -1 + (-s*(x - xc) + y - yc)**2/(m2*(s**2 + 1)) + (
s*(y - yc) + x - xc)**2/(M2*(s**2 + 1))
else:
el = (M2*(s**2 + 1)*(-m2*(s**2 + 1) + (s*(y - yc) - x + xc)**2
) + m2*(s**2 + 1)*(s*(x - xc) + y - yc)**2)/(
M2*m2*(s**2 + 1)**2)
return el.expand().n(n=n)
from sympy import Point
a,b,c = Point(7/5, 12/5), Point(3/2, 5/2), Point(19/10, 3/2)
e3(a,b,c)
e3(b,c,a)
e3(c,a,b)
根据第二个单击点,您将获得1或3个省略号: