Desenhe uma espiral em uma caixa


13

espiral

Essa espiral geométrica parece complicada, mas é bastante simples de desenhar; pegue a seguinte caixa:

caixa

Desenhe uma linha reta entre o canto da caixa e uma certa distância acima do próximo canto no sentido anti-horário.

1 linha

Continue esse padrão para dentro, sempre mantendo essa distância definida no canto da próxima linha. Aqui estão mais algumas linhas.

linhas de moar

Como você pode ver, à medida que o padrão continua, a espiral se aproxima do centro e as caixas que você desenha começam a girar. Observe que a distância permanece constante, independentemente do ângulo.

O desafio

A inspiração (e também graças à pessoa maravilhosa que me apresentou esse conceito <3)

Dada uma entrada numérica (possivelmente fracionária) de 1 a 25, escreva uma imagem no disco que use esse padrão ou exiba a saída na tela, onde a distância de cada canto é a distância de um lado inicial da caixa dividido pela entrada . Continue o padrão para dentro até que a distância do canto especificado seja maior que o comprimento do lado seguinte.

Regras

  • Você não pode usar internos para esta criação em espiral, mas pode usar internos de processamento de imagem.
  • Se você gravar no disco, deverá gerar uma imagem em qualquer um dos formatos .jpg, .gif, .tiff, .pbm, .ppm e .png.
  • O comprimento inicial do lado deve ser de pelo menos 500 pixels.
  • O canto inicial pode ser o que você escolher.
  • Como sempre, as brechas padrão não são permitidas.


Existe um mínimo para quantos níveis de profundidade essa espiral deve ter?
precisa saber é o seguinte

@ LegionMammal978 Eu nunca pediria uma entrada maior que 25, acrescentarei isso.
Addison Crump

Incluir .pbm ou .ppm pode ajudar alguns dos idiomas menos gráficos.
Trichoplax

Respostas:


12

Sapatos (Ruby) 163 bytes

Shoes é um kit de ferramentas GUI baseado em rubi.

Shoes.app{n=ask('').to_f
r=s=5E2
a=[0,s*i="i".to_c,s*i+s,s,0]
(q=a[-3]-a[-4]
r=q.abs/s*n
a<<a[-4]+q/r)while r>1
1.upto(a.size-1){|j|line *(a[j-1].rect+a[j].rect)}}

Ungolfed

Shoes.app{ 
  n=ask('').to_f                 #Open a dialog box with no message, get n from user
  r=s=5E2                        #Initialize s to sidelength=500. r can be initialized to any vale, we use the same one for convenience.
  a=[0,s*i="i".to_c,s*i+s,s,0]   #intialize array a with 5 points needed to draw a square, in complex number format (first point=0 is duplicated.)

  (
    q=a[-3]-a[-4]                #find the vector from point plotted 4 before to the following point (plotted 3 before)
    r=q.abs/s*n                  #r is the scale factor
    a<<a[-4]+q/r                 #add a new point derived from a[-4] by moving toward a[-3] by a distance s/n 
  )while r>1                     #break loop when length of line is less than s/n

  1.upto(a.size-1){|j|           #for all points except 1st and last one
    line *(a[j-1].rect+a[j].rect)#take the two complex numbers correspondimg to the current and previous point,
  }                              #convert to 2-element arrays (rectangular coordinates
}                                #combine to make a 4-element array, use * to splat into 4 parameters, and draw using the line method.

Saídas n = 4 en = 25

insira a descrição da imagem aqui

Observe que a forma sempre termina em um triângulo, que recolhe ainda mais uma linha. Substituir size-1por sizenão faz diferença na aparência da saída e economizaria 2 bytes, mas deixei para a correção teórica.

Saída n = 300

Inspirados por um comentário do OP, os números mais altos parecem ótimos!

insira a descrição da imagem aqui


O espaço a seguir linena linha inferior é necessário?
Addison Crump

@CoolestVeto infelizmente sim. o *converte a matriz de quatro elementos formada pela conversão dos números complexos em quatro parâmetros para line. A sintaxe padrão é line(*(a[j-1].rect+a[j].rect))remover os parênteses e adicionar um espaço já economiza um byte. A remoção do espaço faz com que Ruby tente se multiplicar linepelo conteúdo dos parênteses, o que não faz sentido e causa um erro. Há algum golfe a ser feito aqui, só que não. Vou dar uma olhada mais tarde.
Level River St

Estou quase certo de que você pode se livrar das parênteses em torno da discussão upto. Além disso, você já tentou remover o ('')depois ask? Eu não testei, mas pode ser desnecessário
Ação do Fundo Monica

3
A saída para 100 é linda .
Addison Crump

1
@CoolestVeto Acho n = 100 um pouco perturbador; ele salta e fica todo em 3D em mim. Publiquei n = 300, que é mais escuro no geral e, portanto, mais calmo.
Level River St

3

Java, 1056 1005 985 948 522 508 507 504 502 501 493 492 488 474 465 458 bytes

import java.awt.*;interface G{static void main(String[]a){new Frame(){int s=499,o=s,e,i,x,y;{o/=new Float(a[0]);add(new Component(){public void paint(Graphics g){g.drawRect(0,0,s,s);int[]p={s,s,s,0,0,0,0,s};for(double d=s,t;d>o;t=o/d,i=e*2,x=(int)((1-t)*p[i]+t*p[(2+i)%8]+.5),y=(int)((1-t)*p[1+i]+t*p[(3+i)%8]+.5),g.drawLine(p[(6+i)%8],p[(7+i)%8],x,y),p[i]=x,p[1+i]=y,e=++e%4,i=e*2,x=p[(2+i)%8]-p[i],y=p[(3+i)%8]-p[1+i],d=Math.sqrt(x*x+y*y));}});show();}};}}

Obrigado ao CoolestVeto e ECS por outras formas de reduzir o tamanho. :-)


Ok, eu golfed um pouco mais baixo, mas não é mais possível, com certeza, eu codificado demais para ser :-D caráter minimalista orientada a objetos
Vampiro

@AlexA. Se, posteriormente, melhorar o meu código e torná-lo mais curto, posso simplesmente atualizar a postagem com a versão mais curta?
Vampiro

@ BjörnKautler Sim, isso é bom! :) Estou trabalhando em alguns lugares para diminuir agora.
Addison Crump

1
@ BjörnKautler Você certamente pode!
Alex A.

1
Uau, nunca vi mais de 500 bytes de respostas. : O
Addison Crump

1

Groovy, 412 411 403 398 bytes

import java.awt.*
new Frame(){
def s=499,o=s/(args[0]as float),e=0,i,a,b,d,t
{add new Component(){void paint(Graphics g){g.drawRect 0,0,s,s
p=[s,s,s,0,0,0,0,s]
for(d=s;d>o;d=Math.sqrt(a*a+b*b)){t=o/d
i=e*2
a=(int)((1-t)*p[i]+t*p[(2+i)%8]+0.5)
b=(int)((1-t)*p[1+i]+t*p[(3+i)%8]+0.5)
g.drawLine p[(6+i)%8],p[(7+i)%8],a,b
p[i]=a
p[1+i]=b
e=++e%4
i=e*2
a=p[(2+i)%8]-p[i]
b=p[(3+i)%8]-p[1+i]}}}
show()}}

Tenho problemas para fazê-lo funcionar com Groovy 2.4.4: Caught: groovy.lang.MissingMethodException: No signature of method: static s.div() is applicable for argument types: (java.lang.Float) values: [25.0] Possible solutions: is(java.lang.Object), wait(), run(), run(), find(), any() groovy.lang.MissingMethodException: No signature of method: static s.div() is applicable for argument types: (java.lang.Float) values: [25.0] Possible solutions: is(java.lang.Object), wait(), run(), run(), find(), any() at s$1.<init>(s.groovy:3) at s.run(s.groovy:2)
Dieter

Com o 2.3.9, funciona bem para mim.
Vampiro
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.