Xây dựng n-gons với một thước kẻ và la bàn


16

Nhiệm vụ là vẽ một đa giác đều của n cạnh chỉ bằng một la bàn và một thước kẻ không được đánh dấu.

Đầu vào (n) là một trong 10 số sau: 3, 4, 5, 6, 8, 10, 12, 15, 16, 17.

Phương pháp : Bởi vì bạn chỉ có một thước kẻ và la bàn, bạn chỉ có thể vẽ các điểm, đường và vòng tròn.

Một dòng chỉ có thể được rút ra:

  • thông qua hai điểm hiện có.

Một vòng tròn chỉ có thể được vẽ:

  • với một điểm là tâm của nó và với chu vi của nó đi qua một điểm thứ hai.

Một điểm chỉ có thể được rút ra:

  • tại giao điểm của hai dòng,

  • tại giao điểm của đường thẳng và đường tròn,

  • tại giao điểm của hai vòng tròn,

  • ngay từ đầu, khi bạn có thể rút ra 2 điểm để bắt đầu.

Thông qua quá trình này (và chỉ thông qua quá trình này), bạn phải vẽ n dòng của n-gon được yêu cầu, cùng với bất kỳ công việc cần thiết nào để đến giai đoạn đó.

EDIT: Vị trí của các giao lộ phải được tính toán, nhưng các đường và vòng tròn có thể được vẽ bằng bất kỳ phương tiện nào được cung cấp bởi ngôn ngữ.

Đầu ra là một hình ảnh của một đa giác thông thường n mặt, cho thấy hoạt động.

Về mặt đồ họa không có hạn chế về kích thước hình ảnh, định dạng, độ dày đường hoặc bất cứ điều gì khác không được đề cập ở đây. Tuy nhiên, phải có khả năng phân biệt trực quan các đường, vòng tròn và giao điểm của chúng. Ngoài ra:

  • N dòng tạo nên các cạnh của n-gon của bạn phải là một màu khác với 'công việc' của bạn (tức là bất kỳ điểm, vòng tròn hoặc các dòng khác) và một màu khác một lần nữa cho nền của bạn.
  • Làm việc có thể rời khỏi các đường viền của khu vực vẽ, ngoại trừ các điểm, tất cả phải nằm trong giới hạn có thể nhìn thấy của hình ảnh.
  • Một vòng tròn có thể là một vòng tròn đầy đủ hoặc chỉ là một vòng cung (miễn là nó hiển thị các giao điểm cần thiết).
  • Một dòng là vô hạn (nghĩa là rời khỏi khu vực vẽ) hoặc cắt ở hai điểm nó đi qua. EDIT: Một dòng có thể được vẽ ở bất kỳ độ dài nào. Điểm chỉ có thể được tạo ra khi đường được vẽ giao nhau trực quan.
  • Một điểm có thể được rút ra như bạn muốn, bao gồm cả việc không đánh dấu nó.

Ghi điểm là gấp đôi, một bài nộp được 1 điểm cho mỗi đầu vào mà nó hỗ trợ, tối đa là 10 điểm. Trong trường hợp bốc thăm, số byte ngắn nhất sẽ thắng.

Sự công nhận sẽ được trao cho các bài nộp có thể tạo ra n-gon trong vài bước hoặc có thể tạo các n-gon ngoài phạm vi đã cho, nhưng nó sẽ không giúp bạn ghi điểm.

Thông tin cơ bản từ Wikipedia


Nếu bạn cho phép các đường bị cắt tại các điểm mà chúng được xác định bởi, điều đó có nghĩa là các giao lộ có liên quan có thể nằm ngoài đường được vẽ.
Martin Ender

Chúng ta có thể sử dụng các phím tắt như vẽ hai đoạn thẳng AB và BC bằng cách vẽ một dải ABC đơn, nếu ngôn ngữ của chúng ta cung cấp điều đó?
Martin Ender

1
Là đủ để vẽ xây dựng, hoặc làm chương trình phải tính toán nó là tốt?. Ví dụ: nếu tôi muốn vẽ một vòng tròn tại điểm gốc đi qua điểm (300.400) tôi có thể (biết bán kính là 500) CIRCLE 0,0,500hay tôi phải làm gì R=SQRT(300^2+400^2): CIRCLE 0,0,R? (BTW xử lý các vị trí giao lộ có lẽ khó hơn các đường và vòng tròn.)
Level River St

Từ Wikipedia:Carl Friedrich Gauss in 1796 showed that a regular n-sided polygon can be constructed with straightedge and compass if the odd prime factors of n are distinct Fermat primes
Tiến sĩ belisarius

Thông thường, bạn gọi "thước kẻ không được đánh dấu" là "cạnh thẳng" theo thuật ngữ toán học, giống như trích dẫn của belisarius.
cần

Câu trả lời:


10

BBC Basic, 8 đa giác: 3,4,5,6,8,10,12,15 bên (cũng 60 mặt)

Tải xuống trình giả lập tại http://www.bbcbasic.co.uk/bbcwin/doad.html

Tôi quyết định không bao gồm 16 mặt, đơn giản vì tiền xây dựng của tôi đang trở nên khá bừa bộn. Cần thêm 2 vòng tròn và một dòng. BTW 17 bên thực sự rất phức tạp, và có lẽ sẽ hoạt động tốt nhất như một chương trình riêng biệt.

Tôi đã nhận được nhiều lợi nhuận hơn khi thêm 2 vòng tròn vào công trình ban đầu của mình để tạo ra hình ngũ giác, vì điều này cũng cho phép tôi truy cập vào 10,15 và 60 mặt.

  GCOL 7                               :REM light grey
  z=999                                :REM width of display (in positive and negative direction)
  e=1                                  :REM enable automatic drawing of line through intersections of 2 circles
  DIM m(99),c(99),p(99),q(99),r(99)    :REM array dimensioning for lines and points
  REM lines have a gradient m and y-intercept c. Points have coordinates (p,q) and may be associated with a circle of radius r.

  REM PRECONSTRUCTION

  ORIGIN 500,500
  p(60)=0:q(60)=0                      :REM P60=centre of main circle
  p(15)=240:q(15)=70                   :REM P15=intersection main circle & horiz line
  t=FNr(60,15)                         :REM draw main circle, set radius, SQR(240^2+70^2)=250 units (125 pixels)
  t=FNl(1,60,15)                       :REM L1=horizontal through main circle
  t=FNc(15,45,1,60,-1)                 :REM define P45 as other intersection of main cir and horiz line. overwrite P15 with itself.

  t=FNr(15,45):t=FNr(45,15)            :REM draw 2 large circles to prepare to bisect L1
  t=FNc(61,62,2,45,15)                 :REM bisect L1, forming line L2 and two new points
  t=FNc(30,0,2,60,-1)                  :REM define points P0 and P30 on the crossings of L2 and main circle
  t=FNr(30,60):t=FNc(40,20,3,60,30)    :REM draw circles at P30, and line L3 through intersections with main circle, to define 2 more points
  t=FNr(15,60):t=FNc(25,5,4,60,15)     :REM draw circles at P15, and line L4 through intersections with main circle, to define 2 more points
  t=FNx(63,3,4):t=FNl(5,63,60)         :REM draw L5 at 45 degrees
  t=FNc(64,53,5,60,-1)                 :REM define where L5 cuts the main circle

  e=0                                  :REM disable automatic line drawing through intersections of 2 circles
  GCOL 11                              :REM change to light yellow for the 5 sided preconstruction
  t=FNx(65,1,4):t=FNr(65,0)            :REM draw a circle of radius sqrt(5) at intersection of L1 and L4
  t=FNc(66,67,1,65,-1)                 :REM find point of intersection of this circle with L1
  t=FNr(0,67)                          :REM draw a circle centred at point 0 through that intersection
  t=FNc(36,24,6,60,0)                  :REM find the intersections of this circle with the main circle


  REM USER INPUT AND POLYGON DRAWING

  INPUT d
  g=ASC(MID$("  @@XT u X @  T",d))-64  :REM sides,first point: 3,0; 4,0; 5,24; 6,20; 8,53; 10,24; 12,0; 15,20
  IF d=60 THEN g=24                    :REM bonus polygon 60, first point 24
  FORf=0TOd
    GCOL12                             :REM blue
    h=(g+60DIVd)MOD60                  :REM from array index for first point, calculate array index for second point
    t=FNr(h,g)                         :REM draw circle centred on second point through first point
    t=FNc((h+60DIVd)MOD60,99,99,60,h)  :REM calculate the position of the other intersection of circle with main circle. Assign to new point.
    GCOL9                              :REM red
    LINEp(g),q(g),p(h),q(h)            :REM draw the side
    g=h                                :REM advance through the array
  NEXT

  END

  REM FUNCTIONS

  REM line through a and b
  DEFFNl(n,a,b)
  m(n)=(q(a)-q(b))/(p(a)-p(b))
  c(n)=q(a)-m(n)*p(a)
  LINE -z,c(n)-m(n)*z,z,c(n)+m(n)*z
  =n

  REM radius of circle at point a passing through point b
  DEFFNr(a,b)
  r(a)=SQR((p(a)-p(b))^2+(q(a)-q(b))^2)
  CIRCLEp(a),q(a),r(a)
  =a

  REM intersection of 2 lines: ma*x+ca=mb*x+cb so (ma-mb)x=cb-ca
  DEFFNx(n,a,b)
  p(n)=(c(b)-c(a))/(m(a)-m(b))
  q(n)=m(a)*p(n)+c(a)
  =n

  REM intersection of 2 circles a&b (if b>-1.) The first step is calculating the line through the intersections
  REM if b < 0 the first part of the function is ignored, and the function moves directly to calculating intersection of circle and line.
  REM inspiration from http://math.stackexchange.com/a/256123/137034

  DEFFNc(i,j,n,a,b)
  IF b>-1 c(n)=((r(a)^2-r(b)^2)-(p(a)^2-p(b)^2)-(q(a)^2-q(b)^2))/2/(q(b)-q(a)):m(n)=(p(a)-p(b))/(q(b)-q(a)):IF e LINE -z,c(n)-m(n)*z,z,c(n)+m(n)*z

  REM intersection of circle and line
  REM (mx+ c-q)^2+(x-p)^2=r^2
  REM (m^2+1)x^2 + 2*(m*(c-q)-p)x + (c-q)^2+p^2-r^2=0
  REM quadratic formula for ux^2+vx+w=0 is x=-v/2u +/- SQR(v^2-4*u*w)/2u or x= v/2u +/- SQR((v/2u)^2 - w/u)

  u=m(n)^2+1
  v=-(m(n)*(c(n)-q(a))-p(a))/u               :REM here v corresponds to v/2u in the formula above
  w=SQR(v^2-((c(n)-q(a))^2+p(a)^2-r(a)^2)/u)


  s=SGN(c(n)+m(n)*v-q(a)):IF s=0 THEN s=1    :REM sign of s depends whether midpoint between 2 points to be found is above centre of circle a
  p(i)=v+s*w:q(i)=m(n)*p(i)+c(n)             :REM find point that is clockwise respect to a
  p(j)=v-s*w:q(j)=m(n)*p(j)+c(n)             :REM find point that is anticlockwise respect to a
  =n

Chương trình thực hiện trước khi xây dựng trước khi yêu cầu bất kỳ đầu vào của người dùng. Điều này là đủ để xác định ít nhất 2 điểm trên vòng tròn chính tương ứng với các đỉnh liền kề của hình 3,4,5,6,8,10,12,15 hoặc 60 mặt. Các điểm được lưu trữ trong một tập hợp các mảng 99 phần tử, trong đó các phần tử 0-59 được đặt sang một bên cho các điểm cách đều nhau xung quanh chu vi. Điều này chủ yếu là cho rõ ràng, hình bát giác không hoàn toàn phù hợp với 60 điểm vì vậy cần có sự linh hoạt ở đó (và cả 16 gon nếu nó được bao gồm.) Hình ảnh trông giống như hình ảnh bên dưới, chỉ có màu trắng và xám hai vòng tròn màu vàng được dành riêng cho hình dạng với bội số của 5 mặt. Xem http://en.wikipedia.org/wiki/Pentagon#mediaviewer/File:Regular_Pentagon_Inscribeed_in_a_Circle_240px.gifcho phương pháp vẽ ngũ giác ưa thích của tôi. Các góc độ vui nhộn là để tránh các đường thẳng đứng, vì chương trình không thể xử lý độ dốc vô hạn.

nhập mô tả hình ảnh ở đây

Người dùng nhập một số dcho số lượng bên cần thiết. Chương trình tra cứu trong mảng chỉ số của điểm đầu tiên trong hai điểm (điểm tiếp theo cách 60 / d theo chiều kim đồng hồ.)

Chương trình sau đó lặp lại quá trình vẽ một vòng tròn tập trung vào điểm thứ hai đi qua điểm đầu tiên và tính toán giao điểm mới để đi vòng quanh vòng tròn chính. Các vòng tròn xây dựng được vẽ màu xanh lam, và đa giác cần thiết được vẽ bằng màu đỏ. Những hình ảnh cuối cùng trông như thế này.

Tôi khá hài lòng với họ. BBC Basic thực hiện các tính toán đủ chính xác. Tuy nhiên, rõ ràng (đặc biệt là với 15 và 60 mặt), BBC Basic có xu hướng vẽ các vòng tròn có bán kính nhỏ hơn một chút so với bình thường.

nhập mô tả hình ảnh ở đây


1
Một mẹo tôi đã bỏ qua với điều này là đường 45 độ cắt vòng tròn chính ngay bên cạnh hai vòng tròn có thể được sử dụng để xây dựng 24 gon và 40 gon, cả hai yếu tố là 120. Có hai yếu tố 60 (20 và 30) bị thiếu, sẽ cần thêm một vòng tròn trong cấu trúc trước, để xác định hai góc bị thiếu của hình ngũ giác và đưa ra sự khác biệt 1 / 5-1 / 6 = 1/30 và 1 / 5-1 / 4 = 1/20 . Tuy nhiên tôi không nghĩ rằng tôi sẽ cập nhật câu trả lời của mình vào lúc này. BTW, Cảm ơn tiền thưởng @Martin!
Cấp sông St

16

Mathicala, 2 3 4 đa giác, 759 byte

S=Solve;n=Norm;A=Circle;L=Line;c={#,Norm[#-#2]}&{a_,b_List}~p~{c_,d_List}:=a+l*b/.#&@@S[a+l*b==c+m*d,{l,m}]{a_,b_List}~p~{c_,r_}:=a+l*b/.S[n[c-a-l*b]==r,l]{c_,r_}~p~{d_,q_}:={l,m}/.S[n[c-{l,m}]==r&&n[d-{l,m}]==q,{l,m}]q={0,0};r={1,0};a=q~c~r;b=r~c~q;Graphics@Switch[Input[],3,{s=#&@@p[a,b];A@@@{a,b},Red,L@{q,r,s,q}},4,{k={q,r};{d,e}=a~p~b;j={d,e-d};d=k~p~j~c~q;{e,f}=j~p~d;A@@@{a,b,d},L/@Accumulate/@{k,j},Red,L@{q,e,r,f,q}},6,{d={q,r};e=#&@@d~p~a;f=e~c~q;{g,h}=a~p~f;{i,j}=a~p~b;A@@@{a,b,f},L@{#-2#2,#+2#2}&@@d,Red,L@{r,i,g,e,h,j,r}},8,{k={q,r};{d,e}=a~p~b;j={d,e-d};d=k~p~j~c~q;{e,f}=j~p~d;g=e~c~q;h=q~c~e;i=r~c~e;{o,s}=g~p~h;{t,u}=g~p~i;o={o,2s-2o};s={t,2u-2t};{t,u}=o~p~d;{v,w}=s~p~d;A@@@{a,b,d,g,h,i},L/@Accumulate/@{k,j,o,s},Red,L@{q,t,e,v,r,u,f,w,q}}]

Điểm đạn ngẫu nhiên:

  • Đầu vào được cung cấp thông qua dấu nhắc.
  • Tôi hiện đang hỗ trợ đầu vào 3 , 4 , 6 , 8 .
  • Từ các tùy chọn của bạn, tôi đã chọn các kiểu vẽ đồ thị sau:
    • Vòng tròn đầy đủ.
    • Các dòng từ điểm cuối đến điểm cuối, trừ khi một giao lộ có liên quan nằm bên ngoài, trong trường hợp đó tôi sẽ mã hóa phạm vi.
    • Không có điểm.
    • Hoạt động là màu đen, đa giác là màu đỏ - không phải vì thẩm mỹ mà vì lý do chơi golf.
  • Có một số sao chép mã nghiêm trọng giữa các đa giác. Tôi nghĩ đến một lúc nào đó tôi sẽ chỉ thực hiện một công trình duy nhất cho tất cả chúng, liệt kê tất cả các đường và điểm và vòng tròn trên đường đi, và sau đó chỉ cần giảm Switchđể chọn các vòng tròn và đường liên quan cho mỗi công trình. Bằng cách đó tôi có thể tái sử dụng rất nhiều nguyên thủy giữa chúng.
  • Mã này chứa rất nhiều hàm soạn sẵn xác định tất cả các giao điểm có liên quan và tạo các vòng tròn từ hai điểm.
  • Với điều đó, tôi sẽ thêm nhiều đa giác trong tương lai.

Đây là mã không được mã hóa:

S = Solve;
n = Norm;
A = Circle;
L = Line;
c = {#, Norm[# - #2]} &
{a_, b_List}~p~{c_, d_List} := 
 a + l*b /. # & @@ S[a + l*b == c + m*d, {l, m}]
{a_, b_List}~p~{c_, r_} := a + l*b /. S[n[c - a - l*b] == r, l]
{c_, r_}~p~{d_, q_} := {l, m} /. 
  S[n[c - {l, m}] == r && n[d - {l, m}] == q, {l, m}]
q = {0, 0};
r = {1, 0};
a = q~c~r;
b = r~c~q;
Graphics@Switch[Input[],
  3,
  {
   s = # & @@ p[a, b];
   A @@@ {a, b},
   Red,
   L@{q, r, s, q}
   },
  4,
  {
   k = {q, r};
   {d, e} = a~p~b;
   j = {d, e - d};
   d = k~p~j~c~q;
   {e, f} = j~p~d;
   A @@@ {a, b, d},
   L /@ Accumulate /@ {k, j},
   Red,
   L@{q, e, r, f, q}
   },
  6,
  {
   d = {q, r};
   e = # & @@ d~p~a;
   f = e~c~q;
   {g, h} = a~p~f;
   {i, j} = a~p~b;
   A @@@ {a, b, f},
   L@{# - 2 #2, # + 2 #2} & @@ d,
   Red,
   L@{r, i, g, e, h, j, r}
   },
  8,
  {
   k = {q, r};
   {d, e} = a~p~b;
   j = {d, e - d};
   d = k~p~j~c~q;
   {e, f} = j~p~d;
   g = e~c~q;
   h = q~c~e;
   i = r~c~e;
   {o, s} = g~p~h;
   {t, u} = g~p~i;
   o = {o, 2 s - 2 o};
   s = {t, 2 u - 2 t};
   {t, u} = o~p~d;
   {v, w} = s~p~d;
   A @@@ {a, b, d, g, h, i},
   L /@ Accumulate /@ {k, j, o, s},
   Red,
   L@{q, t, e, v, r, u, f, w, q}
   }
  ]

Và đây là kết quả đầu ra:

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây


Chỉ cần tự hỏi nếu nó sẽ ngắn hơn để mã cứng các dòng và vòng tròn màu đỏ và đen cho mỗi loại đầu vào và vẽ chúng.
Trình tối ưu hóa

@Optimizer Tôi cho rằng các biểu thức chính xác n lớn hơn cho các điểm có lẽ cũng sẽ trở nên khá dài. Tôi nghĩ rằng khi tôi thêm nhiều đa giác, đến một lúc nào đó sẽ có ý nghĩa để tạo một cấu trúc duy nhất cho tất cả chúng, và sau đó chỉ cần chọn các vòng tròn và đường liên quan trong Switch. Điều đó có thể sẽ cho phép tôi sử dụng lại nhiều đường tròn và điểm hơn.
Martin Ender

Tôi này tôi có một cách ngắn hơn để xây dựng hình bát giác, nhưng tôi không chắc làm thế nào để hiển thị nó cho bạn ...
tự hào

@proudhaskeller Vẫn còn ngắn hơn nếu bạn cho rằng 5 dòng đầu tiên của công trình thực sự có thể bị bỏ qua khi sử dụng lại mã từ hình vuông và cách xây dựng này có thể được khái quát hóa để xây dựng bất kỳ 2n-gon nào từ n-gon ? (Cả hai điều, tôi có ý định cải thiện điều này.) Nếu vậy ... ừm ... Tôi cho rằng một mô tả nghiêm ngặt với các điểm được đặt tên như thế này sẽ hoạt động.
Martin Ender

@proudhaskeller Thay vào đó bạn có thể tự đăng nó trước khi tiền thưởng hết hạn. ;)
Martin Ender
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.