Bir cetvel ve pusula ile n-gons oluşturun


16

Görev , yalnızca bir pusula ve işaretlenmemiş bir cetvel kullanarak n kenardan düzenli bir çokgen çizmektir.

(N) girişi aşağıdaki 10 sayıdan biridir: 3, 4, 5, 6, 8, 10, 12, 15, 16, 17.

Yöntem : Yalnızca bir cetveliniz ve pusulanız olduğu için yalnızca noktalar, çizgiler ve daireler çizebilirsiniz.

Bir çizgi yalnızca çizilebilir:

  • mevcut iki nokta üzerinden.

Bir daire yalnızca çizilebilir:

  • merkezi olarak bir nokta ve çevresi ikinci bir noktadan geçer.

Bir nokta sadece çizilebilir:

  • iki çizginin kesiştiği yerde,

  • bir çizginin ve bir dairenin kesişme noktalarında

  • iki dairenin kesişme noktalarında

  • başlangıçta, başlamak için 2 puan çizdiğinizde.

Bu süreçte (ve sadece bu süreçte), istenen aşamaya ulaşmak için gereken herhangi bir çalışma ile birlikte istenen n-gon'un n satırını çizmelisiniz.

EDIT: Kavşakların konumu hesaplanmalıdır, ancak çizgiler ve daireler dil tarafından sağlanan herhangi bir yolla çizilebilir.

Çıktı , çalışmayı gösteren n taraflı düzenli çokgenin bir görüntüsüdür.

Grafiksel olarak görüntü boyutu, formatı, çizgi kalınlığı veya burada belirtilmeyen başka bir şey yoktur. Bununla birlikte, farklı çizgileri, daireleri ve kesişimlerini görsel olarak ayırt etmek mümkün olmalıdır. Bunlara ek olarak:

  • N-gon'unuzun kenarlarını oluşturan n çizgileri, 'çalışma' öğenizden (yani herhangi bir nokta, daire veya diğer çizgiler) farklı bir renk ve arka planınıza göre farklı bir renk olmalıdır.
  • Çalışma, görüntünün görünür sınırları dahilinde olması gereken noktalar hariç, çizim alanının kenarlıklarını bırakabilir.
  • Bir daire tam bir daire veya sadece bir yay olabilir (gerekli kavşakları gösterdiği sürece).
  • Bir çizgi sonsuzdur (yani çizim alanını terk eder) veya içinden geçtiği iki noktada kesilir. EDIT: Herhangi bir uzunlukta bir çizgi çizilebilir. Noktalar yalnızca çizilen çizginin görsel olarak kesiştiği yerlerde oluşturulabilir.
  • İşaretlememek de dahil olmak üzere bir nokta istediğiniz gibi çizilebilir.

Puanlama iki yönlüdür, bir başvuru desteklediği girdi başına en fazla 10 puan için 1 puan alır. Beraberlik durumunda, en kısa bayt sayısı kazanır.

En az adımda n-gons oluşturabilen veya verilen aralığın dışında n-gons oluşturabilen gönderilere tanınır, ancak puanınıza yardımcı olmaz.

Wikipedia'dan arka plan bilgisi


Çizgilerin tanımladıkları noktalarda kesilmesine izin verirseniz, ilgili kesişimler çizilen çizginin dışında olabilir.
Martin Ender

Eğer dilimiz bunu sağlıyorsa, AB ve BC olmak üzere iki çizgi parçasını ABC'ye tek bir çizgi şeridi çizerek çizmek gibi kısayolları kullanabilir miyiz?
Martin Ender

1
Yapıyı çizmek yeterli mi , yoksa program onu da hesaplamak zorunda mı? Örneğin, noktadan (300.400) geçen başlangıç ​​noktasında bir daire çizmek istersem i (yarıçapın 500 olduğunu bilerek) yapabilir miyim CIRCLE 0,0,500yoksa yapmak zorunda mıyım R=SQRT(300^2+400^2): CIRCLE 0,0,R? (BTW kavşak konumları çalışmak muhtemelen çizgi ve dairelerden daha zordur.)
Level River St

Wikipedia'dan: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.Belisarius10

Genellikle "işaretlenmemiş cetvel" i belisarius'un alıntısı gibi matematiksel terimlerle "düz kenar" olarak adlandırırsınız.
justhalf

Yanıtlar:


10

BBC Basic, 8 çokgen: 3,4,5,6,8,10,12,15 kenar (ayrıca 60 kenar)

Emülatörü http://www.bbcbasic.co.uk/bbcwin/download.html adresinden indirin.

16 tarafı dahil etmemeye karar verdim, çünkü ön yapımım oldukça karmaşıklaşıyordu. 2 daire daha ve bir çizgi gerekli olacaktır. BTW 17 tarafları gerçekten çok karmaşıktır ve belki de ayrı bir program olarak en iyisi olacaktır.

Beşgen yapmak için orijinal konstrüksiyonuma 2 daire eklemek için daha fazla geri dönüş aldım, çünkü bu da bana 10,15 ve 60 tarafa erişim verdi.

  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

Program herhangi bir kullanıcı girdisi sormadan önce bir ön yapım yapar. Bu, ana daire üzerinde 3,4,5,6,8,10,12,15 veya 60 taraflı bir şeklin bitişik köşelerine karşılık gelen en az 2 noktayı tanımlamak için yeterlidir. Noktalar, 0-59 elemanlarının çevre çevresinde eşit aralıklı noktalar için bir kenara bırakıldığı bir dizi 99 elemanlı dizide saklanır. Bu esas olarak netlik için, sekizgen 60 noktaya tam olarak uymuyor, bu yüzden orada biraz esneklik gerekiyor (ve ayrıca dahil edildiğinde 16-gon için). Görüntü aşağıdaki resme benziyor, sadece beyaz ve gri renkte, sarıdaki iki daire sadece 5 kenarın katlarına sahip şekillere ayrılmıştır. Bkz. Http://en.wikipedia.org/wiki/Pentagon#mediaviewer/File:Regular_Pentagon_Inscribed_in_a_Circle_240px.giftercih ettiğim beşgen çizim yöntemi. Şans açısı, program sonsuz degradeleri işleyemediğinden dikey çizgilerden kaçınmaktır.

resim açıklamasını buraya girin

Kullanıcı d, gerekli kenar sayısı için bir sayı girer . Program dizide iki noktanın ilkinin dizinini arar (bir sonraki saat saat yönünde 60 / d uzaklıktadır.)

Program daha sonra, ilkinden geçen ikinci noktaya ortalanmış bir daire çizme ve ana dairenin etrafından dolaşmak için yeni kavşağı hesaplama sürecine girer. İnşaat çemberleri mavi, gerekli çokgen kırmızı çizilir. Son görüntüler buna benziyor.

Onlardan oldukça memnunum. BBC Basic hesaplamaları yeterince doğru bir şekilde yapar. Bununla birlikte, BBC Basic'in olması gerekenden biraz daha küçük yarıçaplı daireler çizme eğilimi olduğu açıktır (özellikle 15 ve 60 kenarlı).

resim açıklamasını buraya girin


1
Bununla kaçırdığım bir numara, 45 derecelik çizginin, 24-gon ve 40-gon'u oluşturmak için kullanılabilen iki dairenin hemen yanındaki ana daireyi kesmesidir, her iki faktör de 120'dir. 60 (20 ve 30) pentagonun iki eksik köşesini tanımlamak ve 1 / 5-1 / 6 = 1/30 ve 1 / 5-1 / 4 = 1/20 farklarını vermek için ön yapımda bir daire daha gerektirecek olan eksik . Ancak şu anda cevabımı güncelleyeceğimi sanmıyorum. BTW, @Martin bonusu için teşekkürler!
Level River St

16

Mathematica, 2 3 4 çokgen, 759 bayt

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

Rastgele madde işaretleri:

  • Giriş komut istemi ile sağlanır.
  • Şu anda 3 , 4 , 6 , 8 girişlerini destekliyorum .
  • Seçeneklerinizden aşağıdaki çizim stillerini seçtim:
    • Tam daireler.
    • İlgili bir kavşak dışarıda değilse, uç noktadan uç noktaya doğru olan çizgiler, bu durumda kapsamı sabitlerim.
    • Puan yok.
    • Çalışmalar siyahtır, çokgenler kırmızıdır - estetik değil golf nedenleriyle.
  • Çokgenler arasında ciddi kod çoğaltması var. Sanırım bir noktada, hepsi için tek bir yapı yapacağım, yol boyunca tüm çizgileri ve noktaları ve daireleri numaralandıracağım ve sonra Switchher bir inşaat için ilgili daireleri ve çizgileri seçmek için azaltın . Bu şekilde aralarında çok sayıda ilkel kullanabilirsiniz.
  • Kod, tüm ilgili kavşakları belirleyen ve iki noktadan daire oluşturan çok sayıda kazan plakası işlevi içerir.
  • Bu durumda, gelecekte daha fazla çokgen ekleyeceğim.

İşte ungolfed kodu:

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

Ve işte çıktılar:

resim açıklamasını buraya girin resim açıklamasını buraya girin resim açıklamasını buraya girin resim açıklamasını buraya girin


Her giriş türü için kırmızı ve siyah çizgileri ve daireleri sabit kodlamanın daha kısa olup olmadığını merak edip çizin.
Doktor

@Optimizer Sanırım noktalar için daha büyük n kesin ifadeler de oldukça uzun olacaktır. Daha fazla çokgen eklediğimde, bir noktada hepsi için tek bir yapı yapmak mantıklı olacak ve sonra sadece ilgili daireleri ve çizgileri seçeceksiniz Switch. Bu muhtemelen daha fazla daire çizgisini ve noktasını tekrar kullanmama izin verecek.
Martin Ender

Ben bu sekizgen oluşturmak için daha kısa bir yol var, ama size nasıl göstermek için emin değilim ...
gururlu haskeller

@proudhaskeller Yapının ilk 5 satırının aslında kodu kareden tekrar kullanabileceğini düşünürseniz ve bu şekilde bir n-gon'dan herhangi bir 2n-gon oluşturmak için genelleştirilebileceğini düşünüyorsanız daha kısadır. ? (Her iki şey de, bunu geliştirmeyi aklımda tutuyorum.) Öyleyse ... hmm ... Sanırım bu gibi adlandırılmış noktalara sahip titiz bir açıklama işe yarayacaktır.
Martin Ender

@proudhaskeller Bunun yerine ödülün süresi dolmadan kendin gönderebilirsin. ;)
Martin Ender
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.