定規とコンパスでnゴンを作成する


16

タスクは、コンパスとマークのない定規のみを使用して、n辺の正多角形を描画することです。

入力(n)は、3、4、5、6、8、10、12、15、16、17の10個の数字のいずれかです。

方法:定規とコンパスしか持っていないため、点、線、円のみを描くことができます。

線のみ描画できます:

  • 2つの既存のポイントを介して。

円は描くことができます:

  • 1つのポイントを中心に、その周囲を2番目のポイントを通過します。

ポイントは描画のみ可能です:

  • 2本の線の交点で、

  • 直線と円の交点で、

  • 2つの円の交差点で、

  • 最初に、開始するために2点を引くことができます。

このプロセス(およびこのプロセスのみ)を通じて、要求されたnゴンのn本の線を、その段階に到達するために必要な作業とともに描画する必要があります。

編集:交差点の位置を計算する必要がありますが、線と円は言語が提供する任意の手段で描画できます。

出力は、n辺の正多角形のイメージであり、動作を示しています。

画像のサイズ、フォーマット、線の太さ、またはここで言及されていない他のものには、グラフィック上の制限はありません。ただし、異なる線、円、およびそれらの交差点を視覚的に区別できる必要があります。さらに:

  • n-gonの側面を構成するn本の線は、「作業」(つまり、ポイント、円、または他の線)とは異なる色で、背景とは異なる色でなければなりません。
  • 作業を行うと、描画領域の境界線を残すことができます。ただし、ポイントはすべて画像の可視境界内になければなりません。
  • 円は、完全な円でも円弧でもかまいません(必要な交差点が表示されている限り)。
  • 線は無限(つまり、描画領域を離れる)であるか、通過する2点で切れています。編集:線は任意の長さで描画できます。ポイントは、描画された線が視覚的に交差する場所にのみ作成できます。
  • ポイントは、マークしないことも含め、必要に応じて描画できます。

得点は2つあり、提出は、サポートする入力ごとに1ポイントを取得します(最大10ポイント)。引き分けの場合、最短のバイトカウントが優先されます。

承認は、最も少ないステップでn-gonを作成できるか、指定された範囲外でn-gonを作成できる提出物に与えられますが、スコアに役立ちません。

ウィキペディアの背景情報


定義されたポイントで線を切断できるようにすると、関連する交点が描画された線の外側になる可能性があります。
マーティンエンダー14年

私たちの言語がそれを提供している場合、単一のラインストリップABCをプロットすることにより、2つのラインセグメントABとBCをプロットするようなショートカットを使用できますか?
マーティンエンダー14年

1
構造を描画するだけで十分ですか、それともプログラムで計算する必要がありますか?たとえば、点(300,400)を通過する原点に円を描きたい場合、i(半径が500であることを知っている)はできCIRCLE 0,0,500ますR=SQRT(300^2+400^2): CIRCLE 0,0,Rか?(BTW交差点の位置を計算することは、おそらく線や円よりも困難です。)
レベル川セント14年

ウィキペディアから: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
ベリサリウス博士14年

通常、ベリサリウスによる引用のように、数学用語では「マークのない定規」を「ストレートエッジ」と呼びます。
ちょうど半分14年

回答:


10

BBCベーシック、8ポリゴン:3,4,5,6,8,10,12,15辺(60辺)

http://www.bbcbasic.co.uk/bbcwin/download.htmlからエミュレーターをダウンロードします

私は事前に建設がかなり混雑しているという理由だけで、16面を含めないことにしました。さらに2つの円と線が必要です。BTW 17側は確かに非常に複雑であり、おそらく別のプログラムとして最適でしょう。

元の構造に2つの円を追加して五角形にすることで、10、15、60の側面にアクセスできるようになったため、さらに利益が得られました。

  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

プログラムは、ユーザー入力を求める前に事前構成を行います。これは、3、4、5、6、8、10、12、15、または60面の図の隣接する頂点に対応するメイン円上の少なくとも2つのポイントを定義するのに十分です。ポイントは99要素の配列のセットに格納され、要素0〜59は円周上に等間隔のポイント用に確保されます。これは主に明確にするためであり、八角形は60ポイントに完全には収まらないため、そこにいくらかの柔軟性が必要です(含まれている場合は16角形にも)。画像は以下の画像のように見えます黄色の2つの円は、5辺の倍数を持つ図形専用です。参照くださいhttp://en.wikipedia.org/wiki/Pentagon#mediaviewer/File:Regular_Pentagon_Inscribed_in_a_Circle_240px.gifをください私の好みの五角形の描画方法。プログラムは無限の勾配を処理できないため、垂直角度を避けるために、ja角があります。

ここに画像の説明を入力してください

ユーザーはd必要な面の数を入力します。プログラムは、2つのポイントのうち最初のポイントのインデックスを配列で検索します(次のポイントは時計回りに60 / d離れています)。

次に、プログラムは、最初の点を通る2番目の点を中心とする円を描き、新しい交差点を計算してメイン円の周りを歩くプロセスをループします。下書き円は青で描画され、必要なポリゴンは赤で描画されます。最終的な画像は次のようになります。

私は彼らにとても満足しています。BBC Basicは計算を十分正確に実行します。ただし、BBC Basicは本来よりもわずかに小さい半径の円を描く傾向があることは明らかです(特に15面と60面)。

ここに画像の説明を入力してください


1
私がこれで逃した1つのトリックは、45度の線が24の角と40の角を構築するために使用できる2つの円のすぐ近くでメインの円をカットすることです。 30)五角形の2つの欠落した角を定義し、差1 / 5-1 / 6 = 1/30と1 / 5-1 / 4 = 1/20を与えるために、事前構成でもう1つの円を必要とする欠落。ただし、現時点では回答を更新するとは思わない。ところで、ボーナス@Martinをありがとう!
レベルリバーセント14年

16

Mathematica、2 3 4ポリゴン、759バイト

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

ランダムな弾丸ポイント:

  • 入力はプロンプトを介して提供されます。
  • 私は現在の入力支援しています3468
  • オプションから、次の印刷スタイルを選択しました。
    • 完全な円。
    • 関連する交差点が外側にない限り、エンドポイントからエンドポイントまでの線。その場合、範囲をハードコーディングします。
    • ポイントなし。
    • 作業は黒で、ポリゴンは赤です。見た目ではなく、ゴルフの理由です。
  • ポリゴン間に深刻なコードの重複があります。ある時点で、すべての線と点と円を列挙し、途中ですべての線と点と円を列挙してから、それぞれの線と点Switchに関連する円と線を選択するだけです。そうすれば、それらの間で多くのプリミティブを再利用できます。
  • コードには、関連するすべての交差点を決定し、2点から円を作成する定型関数が多数含まれています。
  • それができたら、将来さらにポリゴンを追加する予定です。

以下に、コード化されていないコードを示します。

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

出力は次のとおりです。

ここに画像の説明を入力してください ここに画像の説明を入力してください ここに画像の説明を入力してください ここに画像の説明を入力してください


入力タイプごとに赤と黒の線と円をハードコーディングして描画する方が短いのではないかと考えています。
オプティマイザー14年

@Optimizer私は、ポイントのより大きなn個の正確な式についても、おそらくかなり長くなると思います。ポリゴンを追加するとき、ある時点ですべてのポリゴンに対して1つの構造を作成してから、で関連する円と線を選択するだけの意味があると思いますSwitch。それはおそらく私がより多くの円の線と点を再利用することを可能にするでしょう。
マーティンエンダー14年

私、この私が八角形を構築する短い方法を持っているが、私は必ずあなたにそれを表示する方法はないよ...
誇りhaskeller

@proudhaskeller構築の最初の5行が実際に正方形からのコードを再利用するために捨てることができ、それを構築するこの方法が潜在的に一般化されてn-gonから2n-gonを構築できると考えるなら、まだ短いですか? ?(両方とも、これを改善することを念頭に置いています。)そうだとしたら...うーん... このような名前の付いた厳密な記述が機能すると思います。
マーティンエンダー14年

@proudhaskeller代わりに、賞金の有効期限が切れる前に自分で投稿することができます。;)
マーティン・エンダー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.