Teğet Çokgen Uzantıları


11

Şuna benzeyen bir şey çizin:

resim açıklamasını buraya girin

Daha kesin bir ifadeyle, l eşit aralıklı teğet çizgisi l olan bir yarıçap r dairesi çizin. Yeni bir n-taraflı düzenli çokgen oluşturmak için bu çizgilerin uçlarını bağlayın.

kurallar

r = daire yarıçapı
n = teğet çizgi sayısı - daire etrafında eşit aralıklı olmalıdır (n> = 3)
l = teğet çizgilerin yan uzunluğu

{R, n, l} bağımsız değişkenlerini kabul eden ve gerekli çıktıyı çizen bir program oluşturun.

Birimler piksel cinsindendir.

Tümü görünür olduğu sürece, çizimin konumuyla ilgili herhangi bir kısıtlama yoktur.

Resim oldukça açıklayıcı.

Bu kod golf, bayt en kısa kod kazanır!


Ben n = = 3 olacağını varsayalım, bir maksimum var mı? Teğet ve daireyi de mi istiyorsun?
MickyT

Evet, n> = 3, (eğer l yeterince uzun değilse kesişme tamam). Daireyi ve teğetleri çizmelisiniz. Bence maksimum çıktı çıktı gölgeli bir daire olduğunda. Başka bir deyişle, maksimum, böyle bir çizim için gerçekçi maksimumdur.
Streç Manyak

Bir vektör grafiği ürettiğimizde piksel birimleri bile geçerli mi? Çünkü böyle bir durumda pikseller aslında oldukça kötü tanımlanmıştır. Ya da biz yapmak zorunda raster grafik üretmek için?
Martin Ender

@ MartinBüttner, bir tür ölçek varsa (eksen gibi) piksel birimini (fantezi) vektör grafiklerinizle yoksayabilirsiniz.
Stretch Maniac

Yanıtlar:


5

Mathematica, 135 132 131 123 bayt

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

Bu kod, girdiyi (bilgi istemiyle) tam olarak soruda belirtildiği gibi bekler: örn {100, 6, 150}. Bir vektör grafiği üretir, bu yüzden OP tarafından yorumlarda belirtildiği gibi bir eksen ekliyorum.

Hem teğetler hem de çokgen aslında "çokgen köşesi, teğet noktası, çokgen köşesi, bir sonraki çokgen köşesi, teğet noktası, çokgen köşesi ..."

resim açıklamasını buraya girin

Eksen için olmasaydı, bunu 107 baytta bile yapabilirdim:

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

Ek tasarruflar (ayrı olarak Axes->1>0) artık her şeyi yeniden ölçeklendirebileceğimden geliyor r, bu da Circlebir birim çemberi elde etme çağrısını basitleştiriyor .


{0,0}~Circle~r
DavidC

@DavidCarraher heh, bunu 135 baytta zaten yapmıştım, ancak not defterini tekrar kopyalamayı unuttum, bu yüzden Unicode değişikliği yaptığımda geri döndü. Teşekkürler!
Martin Ender

8

Python, 133 bayt

Şimdiye kadar "Birimler piksel cinsindendir" kuralına uymanın tek yanı ...

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)

exitonclick()Pencerenin hemen kapanmasını istemiyorsanız sonuna ekleyin .

Çıktı:

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

resim açıklamasını buraya girin

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

resim açıklamasını buraya girin


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


7

T-SQL 440 483

Bu ödüle layık görülmeyecek, ama resim çizmeyi seviyorum :)

Kapsamlı Düzenle ! Sadece daire boyunca çizilen çokgenler için berbat olduğumu fark ettim. Bir maliyetle düzeltildi.

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

Aşağıdaki değişkenlerle yürütülür

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

Sql Server Management Studio 2012 + 'da çalıştırın, uzamsal sonuçlar sekmesinde aşağıdakileri döndürür. resim açıklamasını buraya girin

İle

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

resim açıklamasını buraya girin

ile

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

resim açıklamasını buraya girin

Genişletilmiş

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 

5

MATLAB - 233 bayt

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

İçin örnek fonksiyon çıkışı n = 8, r = 4, l = 6(birim uzunluğunu belirtmek için eksenler dahil edilmiştir): çember çıktı

Örnek fonksiyon çıkışı n = 1024, r = 4, l = 2: çember çıktı


Nit-picking yapıyorum, ancak Birimler piksel cinsindendir
Digital Trauma

3
@DigitalTrauma: Ah. Fark etmedim. MATLAB rakamlarının sabit birimleri yoktur; pencereye doğru ölçeklenirler. Zaten tartışmalı bir nokta. Python'daki LOGO tabanlı çözümünüz benimkini sağlam bir şekilde yendi. Bugünden önce birisinin LOGO'yu Python'a taşıyacağını düşünmezdim, ama işte burada. Ben ilerlerken öğreniyorum. : P
COTO

Peki +1 yine de :)
Dijital Travma

Görüntü neredeyse diyafram logosu.
gururlu haskeller

4

HTML + JavaScript (E6) 298

Test etmek için bir html dosyası olarak kaydedin ve FireFox ile açın. Giriş alanına r, n, l parametrelerini virgülle ayrılmış, sonra sekmeli olarak ekleyin.

Veya jsfiddle'ı deneyin

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

Örnek çıktı

50,20,140

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.