Tâm của một tam giác


13

Các hình tròn và hình vuông có một điểm trung tâm duy nhất, xác định. Tuy nhiên, khái niệm trung tâm của một tam giác đã được thảo luận từ lâu. Bốn trung tâm khác nhau đã được người Hy Lạp cổ đại biết đến:

  • Incenter : Giao điểm của các đường phân giác của tam giác
  • Centroid : Giao điểm của các đường thẳng từ mỗi đỉnh của tam giác đến giữa cạnh đối diện của nó
  • Circumcenter : Giao điểm của đường phân giác vuông góc của các cạnh
  • Orthocenter : Giao điểm của độ cao của tam giác

Euler sau đó đã chứng minh rằng trung tâm, chu vi và orthocenter là cộng tuyến trong bất kỳ tam giác. Đường thẳng mà ba điểm này nằm trong một tam giác được gọi là Đường Euler . Nó được xác định cho mọi tam giác ngoại trừ một tam giác đều, trong đó tất cả các điểm trùng nhau.

Thách thức của bạn là tạo ra chương trình hoặc hàm ngắn nhất, khi được đưa ra hai đầu vào, xuất ra một trung tâm cụ thể hoặc Đường Euler của tam giác. Đầu tiên chỉ định tọa độ của mỗi đỉnh của một tam giác. Thứ hai là một số nguyên từ 1 đến 5, xác định những gì sẽ xuất.

1 - Incenter
2 - Centroid
3 - Circumcenter
4 - Orthocenter
5 - Equation of Euler Line
    (if the Euler Line is vertical, output the `x` value of the line
      (e.g. output `5` if the equation of the line is `x = 5`))

Bạn có thể giả sử rằng các đỉnh đã cho sẽ không bao giờ được cộng tuyến và chúng sẽ luôn là tọa độ nguyên (điều này cũng loại trừ khả năng có một tam giác đều làm đầu vào, theo nhận xét của @ R.Kap ).

Mảng đầu vào phải là một mảng lồng hợp lệ trong ngôn ngữ của bạn và đầu vào phải ở bất kỳ định dạng hợp lý nào. Bất kỳ giá trị float nào sẽ được hiển thị đến ít nhất 3 chữ số thập phân, nhưng không ít hơn. Một điểm xuất ra phải là một mảng hợp lệ trong ngôn ngữ của bạn, phù hợp với định dạng đầu vào.


Các trường hợp thử nghiệm:

Input: [(-2, 0), (1, 0), (0, 1)] 1
Output: (-0.089, 0.451)

Input: [(-2, 0), (1, 0), (0, 1)] 2
Output: (-0.333, 0.333)

Input: [(-2, 0), (1, 0), (0, 1)] 3
Output: (-0.5, -0.5)

Input: [(-2, 0), (1, 0), (0, 1)] 4
Output: (0, 2)

Input: [(-2, 0), (1, 0), (0, 1)] 5
Output: 5x + 2

Làm rõ: Đầu vào có thể từ stdin, khoảng cách hoặc dòng mới được phân tách hoặc làm đối số cho hàm. Đầu ra, tuy nhiên, phải được ghi vào thiết bị xuất chuẩn.


1
Tôi sợ các công thức rõ ràng cho chu vi và orthocenter trong tọa độ cartesian là khá xấu xí. Nếu tôi đi theo cách tạo ra một tọa độ tổng quát / barycentric => carthesian, thì incenter sẽ thoát ra gần như miễn phí. Xem en.wikipedia.org/wiki/Trilinear_coordins#Examples . Tôi có được thêm điểm để thực hiện nó không?
John Dvorak

Các định dạng đầu ra hợp lệ cho dòng Euler là gì? Nếu nó thẳng đứng, nó không thể được thể hiện là y=f(x).
John Dvorak

1
(vui lòng nhận xét nếu bạn không đồng ý) Vui lòng sử dụng hộp cát nếu bạn không chắc chắn liệu thử thách có ổn hay không. Ở đó bạn có thể yêu cầu bình luận và tinh chỉnh câu hỏi cho đến khi nó phù hợp. Sau khi được đăng ở đây, nó không nên được thay đổi liên quan đến nội dung. Một số người có thể đã làm việc với nó - và không thích di chuyển mục tiêu.
Howard

1
"Khi xuất một điểm, tọa độ phải được ... bao quanh trong dấu ngoặc tròn (())". Tại sao yêu cầu này? Trong một số ngôn ngữ, các điểm được thể hiện trong dấu ngoặc nhọn. Và một cái gì đó như (12, -2) chỉ có thể được biểu diễn dưới dạng một chuỗi, trong trường hợp đó, chính các phần tử được hiểu là các chuỗi chứ không phải là số.
DavidC

1
Bạn có thể muốn làm cho đầu vào có thể là tọa độ điểm nổi hoặc loại bỏ hoàn toàn (if the triangle is equilateral, output the point at which the centers meet)không thể tạo ra một tam giác đều trên mặt phẳng tọa độ chỉ sử dụng tọa độ nguyên.
R. Kap

Câu trả lời:


2

Con trăn - 908 870

Dòng mới đã được thêm vào để giảm cuộn. Điều này có thể có thể được chơi golf hơn nữa.

from math import*;t=eval(input());p=int(input())-1;
r=[];A,B,C=t[0],t[1],t[2];
a,b,c=hypot(B[0]-C[0],B[1]-C[1]),hypot(A[0]-C[0],A[1]-C[1]),hypot(A[0]-B[0],A[1]-B[1]);
r.append(((a*A[0]+b*B[0]+c*C[0])/(a+b+c),(a*A[1]+b*B[1]+c*C[1])/(a+b+c)));
r.append(((A[0]+B[0]+C[0])/3,(A[1]+B[1]+C[1])/3));d,e,f=(0,0),(B[0]-A[0],B[1]-A[1]),(C[0]-A[0],C[1]-A[1]);g=2*(e[0]*f[1]-e[1]*f[0]);
r.append(((f[1]*(e[0]**2+e[1]**2)-e[1]*(f[0]**2+f[1]**2))/g+A[0],(e[0]*(f[0]**2+f[1]**2)- f[0]*(e[0]**2+e[1]**2))/g+A[1]));
h=acos((b*b+c*c-a*a)/(2*b*c));i=acos((a*a+c*c-b*b)/(2*a*c));j=acos((a*a+b*b- c*c)/(2*a*b));k=cos(i)*cos(j);
l=cos(h)*cos(j);m=cos(h)*cos(i);r.append(((a*k*A[0]+b*l*B[0]+c*m*C[0])/(a*k+b*l+c*m),(a*k*A[1]+b*l*B[1]+c*m*C[1])/(a*k+b*l+c*m)));
n,o=r[1][0]-r[2][0],r[1][1]-r[2][1];q=r[1][1]-o/n*r[1][0]if n!=0 else 0;
r.append(r[1]if a==b==c else("x="+str(r[1][0])if n==0 else"".join([str(o/n),"x+(",str(q),")"])));print(r[p])

Các trường hợp thử nghiệm (chú thích):

Input: [(-2, 0), (1, 0), (0, 1)]
1
Output: (-0.08907279243665268, 0.45110872103880023) --> More digits than in question

Input: [(-2, 0), (1, 0), (0, 1)]
2
Output: (-0.3333333333333333, 0.3333333333333333) --> More digits than in question

Input: [(-2, 0), (1, 0), (0, 1)]
3
Output: (-0.5, -0.5)

Input: [(-2, 0), (1, 0), (0, 1)]
4
Output: (-1.1702778228588997e-16, 1.9999999999999984) --> More digits than shown in question

Input: [(-2, 0), (1, 0), (0, 1)]
5
Output: 4.999999999999999x+(1.9999999999999996) --> More digits than in question

Như bạn có thể thấy, có thể có lỗi xảy ra do sử dụng dấu phẩy động.


Chơi gôn thêm:

Dựa trên những gợi ý trong các bình luận bên dưới, tôi đã xoay sở để làm cho nó nhỏ hơn.

from math import*;I=input;t=eval(I());p=int(I())-1;r=[];A,B,C=t[0],t[1],t[2];R,H,D,S,T=r.append,hypot,cos,acos,str;a,b,c=H(B[0]-C[0],B[1]-C[1]),H(A[0]-C[0],A[1]-C[1]),H(A[0]-B[0],A[1]-B[1]);R(((a*A[0]+b*B[0]+c*C[0])/(a+b+c),(a*A[1]+b*B[1]+c*C[1])/(a+b+c)));R(((A[0]+B[0]+C[0])/3,(A[1]+B[1]+C[1])/3));d,e,f=(0,0),(B[0]-A[0],B[1]-A[1]),(C[0]-A[0],C[1]-A[1]);g=2*(e[0]*f[1]-e[1]*f[0]);R(((f[1]*(e[0]**2+e[1]**2)-e[1]*(f[0]**2+f[1]**2))/g+A[0],(e[0]*(f[0]**2+f[1]**2)-f[0]*(e[0]**2+e[1]**2))/g+A[1]));h=S((b*b+c*c-a*a)/(2*b*c));i=S((a*a+c*c-b*b)/(2*a*c));j=S((a*a+b*b-c*c)/(2*a*b));k=D(i)*D(j);l=D(h)*D(j);m=D(h)*D(i);R(((a*k*A[0]+b*l*B[0]+c*m*C[0])/(a*k+b*l+c*m),(a*k*A[1]+b*l*B[1]+c*m*C[1])/(a*k+b*l+c*m)));n,o=r[1][0]-r[2][0],r[1][1]-r[2][1];q=r[1][1]-o/n*r[1][0]if n!=0else 0;R(r[1]if a==b==c else("x="+T(r[1][0])if n==0else"".join([T(o/n),"x+(",T(q),")"])));print(r[p])


1
Bạn có thể làm một cái gì đó như R=r.appendvà sau đó sử dụng trong suốt để lưu byte?
FlipTack

1

AutoHotkey - 731

f(z, r:=1){
static 1:="i",2:="m",3:="c",4:="o"
r := %r%,mx :=(z.1.1+z.2.1+z.3.1)/3,my:=(z.1.2+z.2.2+z.3.2)/3
s:=(c:=sqrt((z.2.1-z.1.1)**2+(z.2.2-z.1.2)**2))+(a:=sqrt((z.3.1-z.2.1)**2+(z.3.2-z.2.2)**2))+(b:=sqrt((z.3.1-z.1.1)**2+(z.3.2-z.1.2)**2))
ix:=(a*z.1.1+b*z.2.1+c*z.3.1)/s,iy:=(a*z.1.2+b*z.2.2+c*z.3.2)/s
midx_a:=(z.3.1+z.2.1)/2,midy_a:=(z.3.2+z.2.2)/2,m:=-1*(z.3.1-z.2.1)/(z.3.2-z.2.2),cc_a:=midy_a-(m*midx_a)
midx_b:=(z.3.1+z.1.1)/2,midy_b:=(z.3.2+z.1.2)/2,n:=-1*(z.3.1-z.1.1)/(z.3.2-z.1.2),cc_b:=midy_b-(n*midx_b)
cx:=(cc_b-cc_a)/(m-n),cy:=cc_a+(m*cx),oc_a:=z.1.2-(m*z.1.1),oc_b:=z.2.2-(n*z.2.1),ox:=(oc_a-oc_b)/(n-m),oy:=oc_a+(m*ox)
if r in m,i,c,o
return [%r%x, %r%y]
else return "y=" (m:=(oy-cy)/(ox-cx)) "x+" oy-m*ox
}

Hàm có thể được thu nhỏ hơn (khoảng 600 ký tự HOẶC ít hơn) bằng cách rút ngắn các tên biến như midx_a, midx_b và như vậy.

Gọi hàm

d:=f([[-2, 0], [1, 0], [0, 1]], 1)
for k,v in d
    msgbox % k "`n" v

1

Python 3.5, 851 772 byte:

def H(z,a,b,l):c=complex;T=lambda A,B:abs(c(*A)-c(*B));d=T(z,a);e=T(z,b);f=T(a,b);g=[((a[0]+b[0])/2,(a[1]+b[1])/2)for a,b in[[a,b],[z,a],[b,z]]];E=(z[0]+a[0]+b[0])/3;F=(z[1]+a[1]+b[1])/3;m=lambda f:[(a,0)if(b[1][0]-b[0][0])==0else(a,-1/((b[1][1]-b[0][1])/(b[1][0]-b[0][0])))if(b[1][1]-b[0][1])else''for a,b in zip(f,[[a,b],[z,a],[b,z]])];i=[u for u in m(g)if u!=''];C=i[0][1];D=i[0][0][1]-(C*i[0][0][0]);A=i[1][1];B=i[1][0][1]-(A*i[1][0][0]);G=(B-D)/(C-A);H=C*G+D;j=[u for u in m([z,b,a])if u!=''];C=j[0][1];D=j[0][0][1]-(C*j[0][0][0]);A=j[1][1];B=j[1][0][1]-(A*j[1][0][0]);I=(B-D)/(C-A);J=C*I+D;K,L=[((d*b[o])+(e*a[o])+(f*z[o]))/sum([d,e,f])for o in[0,1]];a=(H-J)/(G-I)if(G-I)else'';b=H-(a*G)if a!=''else G;print(['',(K,L),(E,F),(G,H),(I,J),[b,'%sx+%s'%(a,b)][a!='']][l])

Đưa đầu vào thành một chuỗi các tọa độ được phân tách bằng dấu phẩy, theo sau là một số nguyên truyền đạt những gì cần xuất. Chẳng hạn, nếu tọa độ đầu vào là (1,0),(2,1),(1,4)và bạn muốn trực giao của tam giác tương ứng với các tọa độ đó, bạn chỉ cần gọi hàm như vậy:

H((1,0),(2,1),(1,4),4)

Đầu ra ở định dạng của một tuple nếu cần một điểm cụ thể, ở định dạng của một chuỗi có phương trình ở dạng y=mx+bnếu cần dòng Euler và dòng không thẳng đứng, hoặc đơn giản là xgiá trị của dòng nếu dòng Euler là cần thiết nhưng dòng dọc.

Vì vậy, sử dụng tam giác với các đỉnh (1,0),(2,1),(1,4), các đầu ra sẽ là:

1. Incenter: (1.4663911961440428, 1.125967951102358)
2. Centroid: (1.3333333333333333, 1.6666666666666667)
3. Circumcenter: (0.0, 2.0)
4. Orthocenter: (4.0, 1.0)
5. Euler Line: -0.25x+2.0 

Tôi sẽ cố gắng chơi golf này nhiều hơn theo thời gian ở đâu và khi nào tôi có thể.

Dùng thử trực tuyến! (Ý)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.