Construye n-gons con una regla y una brújula

16

La tarea es dibujar un polígono regular de n lados usando solo una brújula y una regla sin marcar.

La entrada (n) es uno de los siguientes 10 números: 3, 4, 5, 6, 8, 10, 12, 15, 16, 17.

Método : como solo tienes una regla y una brújula, solo puedes dibujar puntos, líneas y círculos.

Solo se puede dibujar una línea:

  • a través de dos puntos existentes.

Un círculo solo se puede dibujar:

  • con un punto como centro y con su perímetro pasando por un segundo punto.

Solo se puede dibujar un punto:

  • en la intersección de dos líneas,

  • en la (s) intersección (es) de una línea y un círculo,

  • en la (s) intersección (es) de dos círculos,

  • Al principio, cuando puedas sacar 2 puntos para comenzar.

A través de este proceso (y solo a través de este proceso) debe dibujar las n líneas del n-gon solicitado, junto con cualquier trabajo requerido para llegar a esa etapa.

EDITAR: Se debe calcular la posición de las intersecciones, pero las líneas y los círculos se pueden dibujar por cualquier medio que proporcione el idioma.

La salida es una imagen de un polígono regular de n lados, que muestra el funcionamiento.

Gráficamente no hay restricciones en el tamaño de la imagen, el formato, el grosor de la línea o cualquier otra cosa que no se mencione aquí. Sin embargo, debe ser posible distinguir visualmente distintas líneas, círculos y sus intersecciones. Adicionalmente:

  • Las n líneas que componen los lados de su n-gon deben ser de un color diferente a su 'trabajo' (es decir, cualquier punto, círculo u otras líneas) y un color diferente nuevamente a su fondo.
  • El trabajo puede dejar los bordes del área de dibujo, excepto los puntos, que deben estar dentro de los límites visibles de la imagen.
  • Un círculo puede ser un círculo completo o simplemente un arco (siempre que muestre las intersecciones requeridas).
  • Una línea es infinita (es decir, abandona el área de dibujo) o está cortada en los dos puntos por los que pasa. EDITAR: Se puede dibujar una línea en cualquier longitud. Los puntos solo se pueden crear donde la línea dibujada se cruza visualmente.
  • Se puede dibujar un punto como desee, incluso sin marcarlo.

La puntuación es doble, una presentación obtiene 1 punto por entrada que admite, para un máximo de 10 puntos. En caso de empate, gana el conteo de bytes más corto.

Se reconocerán las presentaciones que puedan construir n-gons en la menor cantidad de pasos o que puedan construir n-gons fuera del rango dado, pero no ayudará a su puntaje.

Información de fondo de Wikipedia

jsh
fuente
Si permite que las líneas se corten en los puntos por los que están definidas, eso significa que las intersecciones relevantes podrían estar fuera de la línea dibujada.
Martin Ender
¿Podemos usar atajos como trazar dos segmentos de línea AB y BC trazando una sola franja de línea ABC, si nuestro lenguaje lo proporciona?
Martin Ender
1
¿Es suficiente dibujar la construcción, o el programa también tiene que calcularla ? Por ejemplo, si quiero dibujar un círculo en el origen que pasa por el punto (300,400) ¿puedo (sabiendo que el radio es 500) hacerCIRCLE 0,0,500 o debo hacer R=SQRT(300^2+400^2): CIRCLE 0,0,R? (Por cierto, calcular las posiciones de las intersecciones es probablemente más difícil que las líneas y los círculos).
Level River St
De 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
Dr. belisarius
Usualmente llamas "regla sin marcar" como "regla" en términos matemáticos, como la cita de belisario.
justo el

Respuestas:

10

BBC Basic, 8 polígonos: 3,4,5,6,8,10,12,15 lados (también 60 lados)

Descargue el emulador en http://www.bbcbasic.co.uk/bbcwin/download.html

Decidí no incluir 16 lados, simplemente porque mi pre-construcción se estaba volviendo desordenada. Se necesitarían 2 círculos más y una línea. Por cierto 17 lados es muy complicado, y tal vez iría mejor como un programa separado.

Obtuve más rendimiento por agregar 2 círculos a mi construcción original para hacer el pentágono, ya que esto también me dio acceso a 10,15 y 60 lados.

  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

El programa realiza una construcción previa antes de solicitar cualquier entrada del usuario. Esto es suficiente para definir al menos 2 puntos en el círculo principal que corresponden a vértices adyacentes de una figura de 3, 4, 5, 6, 8, 10, 12, 15 o 60 lados. Los puntos se almacenan en un conjunto de matrices de 99 elementos, en los que los elementos 0-59 se reservan para puntos igualmente espaciados alrededor de la circunferencia. Esto es principalmente por claridad, el octágono no encaja perfectamente en 60 puntos, por lo que se necesita cierta flexibilidad allí (y también para el 16-gon si se incluyera). La imagen se ve como la imagen de abajo, en blanco y gris, con solo los dos círculos en amarillo están dedicados exclusivamente a formas con múltiplos de 5 lados. Ver http://en.wikipedia.org/wiki/Pentagon#mediaviewer/File:Regular_Pentagon_Inscriptions_in_a_Circle_240px.gifpara mi método preferido de dibujo del pentágono. El ángulo alegre es evitar las líneas verticales, ya que el programa no puede manejar gradientes infinitos.

ingrese la descripción de la imagen aquí

El usuario ingresa un número dpara el número de lados requeridos. El programa busca en la matriz el índice del primero de los dos puntos (el siguiente está a 60 / d de distancia en sentido horario).

Luego, el programa recorre el proceso de dibujar un círculo centrado en el segundo punto que pasa por el primero, y calcula la nueva intersección para recorrer el círculo principal. Los círculos de construcción se dibujan en azul y el polígono requerido se dibuja en rojo. Las imágenes finales se ven así.

Estoy bastante satisfecho con ellos. BBC Basic realiza los cálculos con suficiente precisión. Sin embargo, es evidente (particularmente con 15 y 60 lados) que BBC Basic tiende a dibujar círculos con un radio un poco más pequeño de lo que debería.

ingrese la descripción de la imagen aquí

Level River St
fuente
1
Un truco que me perdí con esto es que la línea de 45 grados corta el círculo principal justo al lado de dos círculos que se pueden usar para construir el 24-gon y el 40-gon, ambos factores de 120. Hay dos factores de 60 (20 y 30) faltante, lo que requeriría un círculo más en la preconstrucción, para definir las dos esquinas faltantes del pentágono y dar las diferencias 1 / 5-1 / 6 = 1/30 y 1 / 5-1 / 4 = 1/20 . Sin embargo, no creo que esté actualizando mi respuesta en este momento. Por cierto, gracias por el bono @ Martin!
Level River St el
16

Mathematica, 2 3 4 polígonos, 759 bytes

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

Puntos aleatorios:

  • La entrada se proporciona mediante solicitud.
  • Actualmente estoy apoyando las entradas 3 , 4 , 6 , 8 .
  • De sus opciones, elegí los siguientes estilos de trazado:
    • Círculos completos.
    • Líneas de punto final a punto final, a menos que una intersección relevante se encuentre afuera, en cuyo caso codificaré la extensión.
    • Sin puntos.
    • El funcionamiento es negro, los polígonos son rojos, no por razones estéticas sino por razones de golf.
  • Hay una seria duplicación de código entre los polígonos. Creo que en algún momento haré una sola construcción para todos ellos, enumerando todas las líneas, puntos y círculos a lo largo del camino, y luego reduciré Switchpara seleccionar los círculos y líneas relevantes para cada construcción. De esa manera podría reutilizar muchas primitivas entre ellos.
  • El código contiene muchas funciones repetitivas que determinan todas las intersecciones relevantes y crean círculos a partir de dos puntos.
  • Con eso en su lugar, agregaré más polígonos en el futuro.

Aquí está el código sin golf:

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

Y aquí están los resultados:

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Martin Ender
fuente
Me pregunto si sería más corto codificar las líneas y círculos rojos y negros para cada tipo de entrada y dibujarlos.
Optimizador
@Optimizer, supongo que para n expresiones para los puntos, probablemente también sea bastante largo. Creo que cuando agregue más polígonos, en algún momento tendrá sentido hacer una sola construcción para todos ellos, y luego solo seleccionar los círculos y líneas relevantes en el Switch. Eso probablemente me permitiría reutilizar muchas más líneas y puntos circulares.
Martin Ender
Yo esto no tengo un camino más corto para construir el octágono, pero no estoy seguro de cómo mostrar a usted ...
haskeller orgullo
@proudhaskeller ¿Es aún más corto si consideras que las primeras 5 líneas de la construcción en realidad podrían ser abandonadas reutilizando el código del cuadrado, y que esta forma de construirlo podría generalizarse para construir cualquier 2n-gon a partir de un n-gon ? (Ambas cosas, tengo en mente para mejorar esto.) Si es así ... mmm ... supongo que una descripción rigurosa con puntos nombrados como este funcionaría.
Martin Ender
@proudhaskeller En su lugar, puede publicarlo usted mismo antes de que caduque la recompensa. ;)
Martin Ender