Побудуйте n-гони за допомогою лінійки та циркуля


16

Завдання полягає в тому, щоб намалювати звичайний багатокутник з n сторін, використовуючи лише компас і немарковану лінійку.

Введення (n) - це одне з таких 10 чисел: 3, 4, 5, 6, 8, 10, 12, 15, 16, 17.

Спосіб : Оскільки у вас є лише лінійка та компас, ви можете малювати лише точки, лінії та кола.

Рядок може бути намальований лише:

  • через два існуючих пункти.

Коло можна намалювати лише:

  • з однією точкою як центром, а по периметру - через другу точку.

Точку можна зробити лише:

  • на перетині двох ліній,

  • на перетині лінії і кола,

  • на перетині двох кіл,

  • на самому початку, коли ви можете набрати 2 бали, щоб почати.

За допомогою цього процесу (і лише через цей процес) ви повинні намалювати n рядків запитуваного n-gon, а також будь-яку роботу, необхідну для того, щоб дійти до цього етапу.

EDIT: Положення перехресть повинно бути обчислене, але лінії та кола можна намалювати будь-якими способами, передбаченими мовою.

Вихід - це зображення однобічного регулярного багатокутника, що показує працюючий.

Графічно немає жодних обмежень щодо розміру зображення, формату, товщини ліній або чогось іншого, що тут не згадується. Однак повинно бути можливість візуально розрізнити окремі лінії, кола та їх перетини. Додатково:

  • N ліній, що складають сторони вашого n-gon, повинні бути іншого кольору для ваших "працюючих" (тобто будь-яких точок, кіл чи інших ліній) та іншого кольору знову для вашого фону.
  • Робота може залишати межі області малювання, за винятком точок, які повинні бути в межах видимих ​​меж зображення.
  • Коло може бути повним колом або просто дугою (доки воно показує необхідні перетини).
  • Лінія нескінченна (тобто залишає область малювання) або відрізана в двох точках, через які вона проходить. EDIT: Лінія може бути намальована будь-якої довжини. Точки можна створити лише там, де намальована лінія візуально перетинається.
  • Точку можна намалювати за вашим бажанням, включаючи не позначаючи її.

Підрахунок балів є подвійним, подання отримує 1 бал за підтримку, яку він підтримує, максимум 10 балів. У разі жеребкування виграє найменший байт.

Визнання буде надано поданням, які можуть побудувати n-gons за найменші кроки або здатні сконструювати n-gons поза вказаним діапазоном, але це не допоможе вашому балу.

Довідкова інформація з Вікіпедії


Якщо ви дозволяєте відрізати лінії в точках, визначених ними, це означає, що відповідні перетини можуть бути поза накресленою лінією.
Мартін Ендер

Чи можемо ми використати ярлики, як побудувати два відрізки AB і BC, побудувавши однорядну смугу ABC, якщо наша мова це забезпечує?
Мартін Ендер

1
Чи достатньо намалювати конструкцію, чи програма також повинна її обчислити ? Наприклад, якщо я хочу намалювати коло біля початку, що проходить через точку (300 400), чи можу я (знаючи радіус 500), CIRCLE 0,0,500чи потрібно це робити R=SQRT(300^2+400^2): CIRCLE 0,0,R? (BTW відпрацьовує місця перехресть, напевно, складніше, ніж лінії та кола.)
рівень річки St

З Вікіпедії: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
Д-р belisarius

Зазвичай ви називаєте "немаркований лінійку" математичний термін як "прямий край", як цитата Белізарія.
justhalf

Відповіді:


10

BBC Basic, 8 полігонів: 3,4,5,6,8,10,12,15 сторони (також 60 сторін)

Завантажте емулятор за адресою http://www.bbcbasic.co.uk/bbcwin/download.html

Я вирішив не включати 16 сторін, просто тому, що моя попередня конструкція стала досить захаращеною. Ще 2 кола і рядок знадобиться. BTW 17 сторін дійсно дуже складний, і, можливо, найкраще піде як окрема програма.

Я отримав більше повернення за додавання 2-х кіл до моєї оригінальної конструкції, щоб зробити п’ятикутник, оскільки це також дало мені доступ до 10,15 та 60 сторін.

  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

Програма робить попередню побудову перед тим, як запитувати будь-який ввід користувача. Цього достатньо, щоб визначити принаймні 2 точки на головному колі, які відповідають суміжним вершинам 3,4,5,6,8,10,12,15 або 60-сторонній фігурі. Точки зберігаються у наборі 99-елементних масивів, у яких елементи 0-59 відкладаються для однаково розташованих точок по колу. Це в основному для наочності, восьмикутник не ідеально вписується в 60 балів, тому потрібна деяка гнучкість (а також для 16-гронних, якщо б вони були включені.) Зображення виглядає як зображення внизу, білого та сірого, лише два жовті кола, присвячені виключно фігурам, кратним 5 сторонам. Дивіться http://en.wikipedia.org/wiki/Pentagon#mediaviewer/File:Regular_Pentagon_Inscribed_in_a_Circle_240px.gifдля мого кращого методу малювання п’ятикутника. Кут жалюзі полягає у униканні вертикальних ліній, оскільки програма не може обробляти нескінченні градієнти.

введіть тут опис зображення

Користувач вводить число dна кількість необхідних сторін. Програма шукає в масиві індекс першої з двох точок (наступна відстань на 60 / д за годинниковою стрілкою.)

Потім програма проходить цикл прорисування кола, зосередженого на другій точці, що проходить через першу, і обчислення нового перетину, щоб пройти шлях по головному колу. Будівельні кола намальовані синім кольором, а необхідний багатокутник - червоним. Кінцеві зображення виглядають приблизно так.

Я цілком задоволений ними. BBC Basic виконує розрахунки досить точно. Однак очевидно (особливо з 15 та 60 сторін), що BBC Basic має тенденцію малювати кола з трохи меншим радіусом, ніж слід.

введіть тут опис зображення


1
Один трюк, який я пропустив з цього приводу, полягає в тому, що 45-градусна лінія розрізає основне коло поруч з двома колами, які можна використовувати для побудови 24-го і 40-го, обох факторів 120. Є два фактори 60 (20 і 30) відсутній, який потребував би ще одного кола в попередній конструкції, визначити два відсутні кути п’ятикутника і дати відмінності 1 / 5-1 / 6 = 1/30 і 1 / 5-1 / 4 = 1/20 . Однак я не думаю, що я зараз оновлюю свою відповідь. BTW, спасибі за бонус @Martin!
Рівень р. Св.

16

Математика, 2 3 4 багатокутники, 759 байт

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

Випадкові кулі:

  • Введення даних здійснюється за допомогою підказки.
  • На даний момент я підтримую входи 3 , 4 , 6 , 8 .
  • З ваших варіантів я вибрав такі стилі накреслення:
    • Повні кола.
    • Рядки від кінцевої точки до кінцевої точки, якщо не знаходиться зовнішнє перехрестя, і в такому випадку я зашифрую міру.
    • Балів немає.
    • Роботи чорні, багатокутники червоні - не з естетичних, а з міркувань гольфу.
  • Існує деяке серйозне дублювання коду між полігонами. Я думаю, що в якийсь момент я просто зроблю єдину конструкцію для всіх, перелічуючи всі лінії та точки та кола по дорозі, а потім просто зменшу, Switchщоб вибрати відповідні кола та лінії для кожної конструкції. Таким чином я міг повторно використовувати багато примітивів між ними.
  • Код містить безліч функцій шахти, які визначають усі відповідні перехрестя та створюють кола з двох точок.
  • Маючи це на місці, я в майбутньому буду додавати більше полігонів.

Ось код, який не використовується для гольфу:

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

І ось результати:

введіть тут опис зображення введіть тут опис зображення введіть тут опис зображення введіть тут опис зображення


Цікаво, чи буде коротше жорсткого коду червоних та чорних ліній та кіл для кожного типу введення та намалювати їх.
Оптимізатор

@Optimizer Я думаю, що для більших n точних виразів для очок, ймовірно, теж стане досить довгим. Я думаю, що коли я додаю більше багатокутників, в якийсь момент буде сенс зробити одну єдину конструкцію для всіх, а потім просто вибрати відповідні кола та лінії в Switch. Це, ймовірно, дозволить мені використовувати набагато більше ліній та точок кола.
Мартін Ендер

У мене це у мене коротший спосіб побудувати восьмикутник, але я не впевнений, як це показати вам ...
гордий haskeller

@proudhaskeller Це ще коротше, якщо врахувати, що перші 5 рядків конструкції насправді можуть бути викреслені, повторно використовуючи код з квадрата, і що цей спосіб його побудови потенційно може бути узагальнений для побудови будь-якого 2n-gon з n-gon ? (Обидві речі, я маю на увазі покращення цього.) Якщо так ... гммм ... я вважаю, що жорсткий опис із названими пунктами, як цей , спрацював би.
Мартін Ендер

@proudhaskeller Ви можете замість цього опублікувати самостійно до закінчення виграшної суми. ;)
Мартін Ендер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.