Ekstensi Polygon Tangent

11

Gambar sesuatu yang terlihat seperti ini:

masukkan deskripsi gambar di sini

Dalam istilah yang lebih tepat, gambarlah lingkaran dengan jari-jari r, dengan n garis-garis singgung panjang yang merata l. Hubungkan ujung garis-garis ini untuk membentuk poligon reguler n-sided baru.

Aturan

r = jari-jari lingkaran
n = jumlah garis singgung - harus ditempatkan secara merata di sekitar lingkaran (n> = 3)
l = panjang sisi garis singgung

Buat program yang menerima argumen {r, n, l} dan menggambar output yang diperlukan.

Unit dalam piksel.

Tidak ada batasan untuk lokasi gambar, asalkan semuanya terlihat.

Gambarnya cukup jelas.

Ini adalah kode-golf, jadi kode terpendek dalam byte menang!

Regangkan Maniac
sumber
Saya berasumsi n akan> = 3, adakah yang maksimal? Apakah Anda ingin garis singgung dan lingkaran juga?
MickyT
Ya, n> = 3, (persimpangan di ok jika l tidak cukup panjang). Anda harus menggambar lingkaran dan garis singgung. Saya pikir maksimum pada dasarnya ketika output adalah lingkaran berbayang. Dengan kata lain, maksimum adalah maksimum realistis untuk gambar seperti ini.
Stretch Maniac
Apakah satuan piksel berlaku jika kita menghasilkan grafik vektor? Karena dalam kasus seperti itu piksel sebenarnya cukup tidak jelas. Atau apakah kita harus menghasilkan grafis raster?
Martin Ender
@ MartinBüttner, Anda dapat mengabaikan unit piksel dengan grafik vektor (mewah) Anda jika ada semacam skala (seperti sumbu).
Stretch Maniac

Jawaban:

5

Mathematica, 135 132 131 123 byte

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

Kode ini mengharapkan input (melalui prompt) persis seperti yang ditentukan dalam pertanyaan: mis {100, 6, 150}. Ini menghasilkan grafik vektor, jadi saya termasuk sumbu, sebagaimana ditentukan dalam komentar oleh OP.

Kedua garis singgung dan poligon sebenarnya adalah satu garis garis, dengan melintasi "sudut poligon, titik singgung, sudut poligon, sudut poligon berikutnya, titik singgung, sudut poligon ..."

masukkan deskripsi gambar di sini

Jika bukan karena sumbu, saya bahkan bisa melakukan ini dalam 107 byte:

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

Penghematan tambahan (terlepas dari Axes->1>0) berasal dari kenyataan bahwa saya sekarang dapat rmengubah Circleskala semuanya dengan , yang menyederhanakan panggilan untuk menghasilkan lingkaran unit.

Martin Ender
sumber
{0,0}~Circle~r
DavidC
@ David Carraher heh, saya sebenarnya sudah melakukan itu dalam 135 byte, tetapi lupa untuk menyalinnya kembali ke notebook saya, jadi itu dikembalikan ketika saya membuat perubahan Unicode. Terima kasih!
Martin Ender
8

Python, 133 byte

Satu-satunya jawaban sejauh ini untuk mematuhi aturan "Unit dalam piksel" ...

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)

Tambahkan exitonclick()ke akhir jika Anda tidak ingin jendela segera ditutup.

Keluaran:

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

masukkan deskripsi gambar di sini

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

masukkan deskripsi gambar di sini

Trauma Digital
sumber
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
Cobalah online
mbomb007
7

T-SQL 440 483

Tidak akan memenangkan hadiah dengan yang satu ini, tapi saya suka menggambar gambar :)

Edit sumpah serapah! Hanya memperhatikan saya mengacaukan poligon yang ditarik melintasi lingkaran. Diperbaiki dengan biaya.

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

Dilaksanakan dengan variabel-variabel berikut

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

Jalankan di Sql Server Management Studio 2012+ itu akan mengembalikan yang berikut di tab hasil spasial. masukkan deskripsi gambar di sini

Dengan

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

masukkan deskripsi gambar di sini

dengan

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

masukkan deskripsi gambar di sini

Diperluas

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
sumber
5

MATLAB - 233 byte

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);

Output fungsi sampel untuk n = 8, r = 4, l = 6(sumbu disertakan untuk menunjukkan panjang unit): keluaran circpoly

Output fungsi sampel untuk n = 1024, r = 4, l = 2: keluaran circpoly

COTO
sumber
Saya nit-picking, tetapi Unit dalam piksel
Digital Trauma
3
@DigitalTrauma: Ah. Tidak memperhatikan itu. Angka MATLAB tidak memiliki unit tetap; mereka menskalakan ke jendela. Dan itu adalah poin yang bisa diperdebatkan. Solusi berbasis LOGO Anda di Python telah mengalahkan saya. Sebelum hari ini saya tidak akan membayangkan seseorang akan port LOGO ke Python, tetapi itu dia. Saya belajar sambil jalan. : P
COTO
Yah +1 tetap :)
Digital Trauma
Gambar hampir logo aperture.
haskeller bangga
4

HTML + JavaScript (E6) 298

Untuk menguji, simpan sebagai file html dan buka dengan FireFox. Masukkan parameter r, n, l ke dalam kolom input, pisahkan koma, lalu tab out.

Atau coba 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>

Output sampel

50,20.140

edc65
sumber