삼각형의 중심


13

원과 사각형에는 하나의 명확한 중심점이 있습니다. 그러나 삼각형 중심의 개념은 오랫동안 논의되었습니다. 고대 그리스인들에게 네 가지 센터가 알려졌습니다.

  • 중심 : 삼각형의 각도 이등분선의 교차점
  • 중심 : 삼각형의 각 꼭짓점에서 반대쪽의 중간 점까지의 선의 교차점
  • 둘레 중심 : 측면의 수직 이등분선의 교차점
  • Orthocenter : 삼각형 고도의 교차점

오일러는 나중에 중심, 둘레 중심 및 직교 중심이 어떤 삼각형에서도 동일 선상에 있음을 증명했습니다. 이 세 점이 삼각형에있는 선을 오일러 선 이라고합니다 . 모든 점이 일치하는 정삼각형을 제외한 모든 삼각형에 대해 정의됩니다.

두 개의 입력이 주어지면 특정 센터 또는 삼각형의 오일러 라인을 출력하는 가장 짧은 프로그램이나 함수를 만드는 것이 도전입니다. 첫 번째는 삼각형의 각 꼭짓점의 좌표를 지정합니다. 두 번째는 1에서 5까지의 정수이며 출력 대상을 결정합니다.

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`))

주어진 정점이 결코 동일 선상에 있지 않을 것이고 항상 정수 좌표가 될 것이라고 가정 할 수 있습니다 ( @ R.Kap의 설명에 따라 등변 삼각형을 입력으로 사용할 가능성을 배제합니다 ).

입력 배열은 사용자 언어로 유효한 중첩 배열이어야하며 입력은 적절한 형식이어야합니다. 부동 소수점 값은 소수점 이하 3 자리 이상으로 표시해야합니다. 출력 포인트는 입력 형식과 일치하는 언어로 유효한 배열이어야합니다.


테스트 사례 :

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

설명 : 입력은 stdin에서 시작하거나 공백 또는 줄 바꾸기로 분리되거나 함수에 대한 인수로 사용될 수 있습니다. 그러나 출력은 stdout에 기록되어야합니다.


1
직교 좌표계의 둘레 중심과 직교 중심에 대한 명시 적 공식이 꽤 추악합니다. 일반적인 trilinear / barycentric => 카테 시안 좌표를 만드는 방법을 사용하면 중심이 거의 자유 롭습니다. en.wikipedia.org/wiki/Trilinear_coordinates#Examples를 참조하십시오 . 그것을 구현하기 위해 추가 포인트를 얻습니까?
John Dvorak

오일러 라인의 유효한 출력 형식은 무엇입니까? 세로이면로 표현할 수 없습니다 y=f(x).
John Dvorak

1
(동의하지 않을 경우 의견을 보내 주십시오 ) 도전이 맞는지 확실하지 않은 경우 샌드 박스를 사용 하십시오. 거기에서 당신은 의견을 요구하고 그것이 맞을 때까지 질문을 구체화 할 수 있습니다. 여기에 게시 된 후에는 내용과 관련하여 변경해서는 안됩니다. 여러 사람들이 이미 그 일을하고있을 수도 있으며 움직이는 목표물을 좋아하지 않습니다.
Howard

1
"점을 출력 할 때 좌표는 둥근 괄호 (())로 묶어야합니다." 왜 이런 요구 사항입니까? 일부 언어에서는 점이 중괄호로 표시됩니다. 그리고 (12, -2)와 같은 것은 문자열로만 표현 될 수 있으며,이 경우 요소 자체는 숫자가 아닌 문자열로 해석됩니다.
DavidC

1
당신도 입력이 부동 소수점 좌표, 또는 완전히 제거 할 수 그것을 있는지 확인 할 수 있습니다 (if the triangle is equilateral, output the point at which the centers meet)그대로 하지 좌표 정수를 이용하여 좌표 평면 정삼각형을 만들 수 있습니다.
R. Kap

답변:


2

파이썬 - 908 870

스크롤을 줄이기 위해 줄 바꿈이 추가되었습니다. 이것은 아마도 더 골프 될 수 있습니다.

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])

테스트 사례 (주석) :

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

보시다시피 부동 소수점을 사용하면 오류가 발생할 수 있습니다.


추가 골프 :

아래 의견의 제안에 따라이 크기를 작게 만들었습니다.

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
R=r.append바이트를 절약하기 위해 비슷한 것을 할 수 있습니까?
FlipTack

1

오토 핫키-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
}

midx_a, midx_b 등과 같은 변수 이름을 줄임으로써 함수를보다 약화 (약 600 자 이하) 할 수 있습니다.

함수 호출

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

1

Python 3.5, 851 772 바이트 :

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])

취하고 입력을 출력에 어떻게 전달하는 정수가 콤마로 구분 좌표의 순서로. 예를 들어 입력 좌표가 (1,0),(2,1),(1,4)있고 해당 좌표에 해당하는 삼각형의 직교 중심을 원한다면 다음과 같이 함수를 호출하면됩니다.

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

출력 튜플의 형식은 특정 포인트 형태로 식 문자열의 형식으로, 필요한 경우, y=mx+b오일러 라인이 필요한 경우 라인은 없다 수직 또는 단순히 x광고 오일러 줄 경우의 값 필요하지만 선 수직입니다.

따라서 vertices가있는 삼각형을 사용하면 (1,0),(2,1),(1,4)출력은 다음과 같습니다.

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 

언제 어디서나 골프를하려고 노력할 것입니다.

온라인으로 사용해보십시오! (아이디어)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.