Extensões de polígono tangente

11

Desenhe algo parecido com isto:

insira a descrição da imagem aqui

Em termos mais precisos, desenhe um círculo de raio r, com n espaços iguais de linhas tangentes de comprimento l. Conecte as extremidades dessas linhas para formar um novo polígono regular de n lados.

Regras

r = raio do círculo
n = número de linhas tangentes - deve estar uniformemente espaçado ao redor do círculo (n> = 3)
l = comprimento lateral das linhas tangentes

Crie um programa que aceite os argumentos {r, n, l} e desenhe a saída necessária.

As unidades estão em pixels.

Não há restrições para a localização do desenho, desde que tudo esteja visível.

A imagem é bastante auto-explicativa.

Isso é código-golfe, então o código mais curto em bytes vence!

Stretch Maniac
fonte
Presumo que n será> = 3, existe um máximo? Você quer as tangentes e o círculo também?
MickyT
Sim, n> = 3, (interseção em ok se l não for longo o suficiente). Você deve desenhar o círculo e as tangentes. Eu acho que o máximo é basicamente quando a saída é um círculo sombreado. Em outras palavras, o máximo é o máximo realista para um desenho como este.
Stretch Maniac #
As unidades de pixel se aplicam mesmo se produzirmos um gráfico vetorial? Porque nesse caso, os pixels são realmente mal definidos. Ou temos que produzir gráficos rasterizados?
Martin Ender
@ MartinBüttner, você pode ignorar a unidade de pixel com seus gráficos vetoriais (sofisticados) se houver algum tipo de escala (como um eixo).
Stretch Maniac

Respostas:

5

Mathematica, 135 132 131 123 123 bytes

{r,n,l}=Input[];Graphics[{{0,0}~Circle~r,Line[Join@@Array[{b=(a=r{c=Cos[t=2Pi#/n],s=Sin@t})-l{s,-c},a,b}&,n+1]]},Axes->1>0]

Este código espera a entrada (via prompt) exatamente como especificado na pergunta: por exemplo {100, 6, 150}. Ele produz um gráfico vetorial, por isso estou incluindo um eixo, conforme especificado nos comentários do OP.

As tangentes e o polígono são na verdade uma única faixa de linha, percorrendo "canto do polígono, ponto tangente, canto do polígono, próximo canto do polígono, ponto tangente, canto do polígono ..."

insira a descrição da imagem aqui

Se não fosse o eixo, eu poderia fazer isso em 107 bytes:

{r,n,l}=Input[];Graphics@{Circle[],Line[Join@@Array[{b=(a={c=Cos[t=2Pi#/n],s=Sin@t})-l/r{s,-c},a,b}&,n+1]]}

Economias adicionais (além de Axes->1>0) vêm do fato de que agora posso redimensionar tudo r, o que simplifica a chamada para Circlegerar um círculo unitário.

Martin Ender
fonte
{0,0}~Circle~r
DavidC
@DavidCarraher heh, eu já tinha feito isso nos 135 bytes, mas esqueci de copiá-lo novamente no meu notebook, então ele foi revertido quando fiz a alteração do Unicode. obrigado!
Martin Ender
8

Python, 133 bytes

Até agora, a única resposta para cumprir a regra "As unidades estão em pixels" ...

from turtle import*
c=circle
r,n,l=input()
lt(90)
exec'c(r,360/n);fd(l);bk(l);'*n
fd(l)
lt(towards(-r,0)-180)
c(distance(-r,0),360,n)

Adicione exitonclick()ao final se você não quiser que a janela se feche imediatamente.

Resultado:

python tangentpoly.py <<< "20, 6, 30":

insira a descrição da imagem aqui

python tangentpoly.py <<< "100, 8, 200":

insira a descrição da imagem aqui

Trauma Digital
fonte
1
for i in n*[0]:c(r,360/n);fd(l);bk(l)->exec'c(r,360/n);fd(l);bk(l)'*n;
isaacg
1
Experimente online
mbomb007
7

T-SQL 440 483

Não vou ganhar nenhum prêmio com este, mas eu gosto de desenhar :)

Editar palavrões! Só notei que errei por polígonos desenhados em todo o círculo. Corrigido a um custo.

SELECT Geometry::UnionAggregate(Geometry::Point(0,0,0).STBuffer(@r).STExteriorRing().STUnion(Geometry::STGeomFromText(CONCAT('LINESTRING(',@r*SIN(a),' ',@r*COS(a),',',@r*SIN(a)+@l*SIN(b),' ',@r*COS(a)+@l*COS(b),')'),0))).STUnion(Geometry::ConvexHullAggregate(Geometry::Point(@r*SIN(a)+@l*SIN(b),@r*COS(a)+@l*COS(b),0)).STExteriorRing())p FROM(SELECT RADIANS(360./@*N)a,RADIANS((360./@*N)-90)b FROM(SELECT TOP(@)row_number()OVER(ORDER BY(SELECT\))-1N FROM sys.types a,sys.types b)t)r

Executado com as seguintes variáveis

declare @r float = 1.0
declare @ int = 10
declare @l float = 3.0

Executar no Sql Server Management Studio 2012+, ele retornará o seguinte na guia de resultados espaciais. insira a descrição da imagem aqui

Com

declare @r float = 1.0
declare @ int = 360
declare @l float = 3.0

insira a descrição da imagem aqui

com

declare @r float = 10.0
declare @ int = 3
declare @l float = 10.0

insira a descrição da imagem aqui

Expandido

SELECT Geometry::UnionAggregate(    --group together lines
    Geometry::Point(0,0,0)          --Set origin
    .STBuffer(@r)                   --Buffer to @r
    .STExteriorRing()               --Make it a line
    .STUnion(                       --Join to the floowing tangent
        Geometry::STGeomFromText(   --Create a tangent line
            CONCAT('LINESTRING(',@r*SIN(a),' ',@r*COS(a),',',@r*SIN(a)+@l*SIN(b),' ',@r*COS(a)+@l*COS(b),')'),0)
        )
    ).STUnion( --Generate polygon around exterior points
    Geometry::ConvexHullAggregate(Geometry::Point(@r*SIN(a)+@l*SIN(b),@r*COS(a)+@l*COS(b),0)).STExteriorRing()
    )
    p
FROM(
    SELECT RADIANS(360./@*N)a,      --calclate bearings
        RADIANS((360./@*N)-90)b
    FROM(                           --make enough rows to draw tangents
        SELECT TOP(@)row_number()OVER(ORDER BY(SELECT\))-1N 
        FROM sys.types a,sys.types b
        )t
    )r 
MickyT
fonte
5

MATLAB - 233 bytes

function C(n,r,l),t=2*pi/n;c=cos(t);s=sin(t);M=[c,s;-s,c];F=@(y)cell2mat(arrayfun(@(x){M^x*y},1:n));P=F([0;r]);Q=F([l;r]);v='k';t=1e3;t=2*pi/t*(0:t);R=[1:n 1];q=Q(1,R);s=Q(2,R);plot(r*cos(t),r*sin(t),v,[P(1,R);q],[P(2,R);s],v,q,s,v);

Saída da função de amostra para n = 8, r = 4, l = 6(eixos incluídos para indicar o comprimento da unidade): saída circpoly

Saída da função de amostra para n = 1024, r = 4, l = 2: saída circpoly

COTO
fonte
Estou-picking nit, mas unidades estão em pixels
Digital Trauma
3
@DigitalTrauma: Ah. Não percebi isso. Os números do MATLAB não possuem unidades fixas; eles escalam para a janela. E é um ponto discutível de qualquer maneira. Sua solução baseada em LOGO em Python bateu a minha profundamente. Antes de hoje, eu não imaginava que alguém portaria o LOGO no Python, mas aí está. Estou aprendendo à medida que avança. : P
COTO
Bem +1 de qualquer maneira :)
Digital Trauma
A imagem é quase o logotipo da abertura.
haskeller orgulhoso
4

HTML + JavaScript (E6) 298

Para testar, salve como um arquivo html e abra com o FireFox. Insira os parâmetros r, n, l no campo de entrada, separados por vírgula e, em seguida, tabule.

Ou tente jsfiddle

<input onblur="
[r,n,l]=this.value.split(','),
z=r-~l,t=D.getContext('2d'),w='lineTo',
D.width=D.height=z*2,
t.arc(z,z,r,0,7);
for(C=1,S=i=0;i++<n;)
  t[w](x=z+r*C,y=z+r*S),
  t[w](x-l*S,y+l*C),
  C=Math.cos(a=6.283*i/n),
  S=Math.sin(a),
  t[w](z+r*C-l*S,z+r*S+l*C);
t.stroke()">
<canvas id=D>

Saída de amostra

50,20.140

edc65
fonte