用尺子和罗盘构造n-gons


16

任务是仅使用指南针和未标记的标尺绘制n边的规则多边形。

输入(n)是以下10个数字之一:3、4、5、6、8、10、12、15、16、17

方法:因为只有标尺和罗盘,所以只能绘制点,线和圆。

只能画一条线:

  • 通过两个现有点。

只能画一个圆:

  • 以一个点为中心,周长穿过第二个点。

只能画一个点:

  • 在两条线的交点,

  • 在直线和圆的交点处,

  • 在两个圆的交点处,

  • 一开始,您可能会画2点以开始。

通过此过程(并且仅通过此过程),您必须绘制所请求的n-gon的n条线以及达到该阶段所需的所有工作。

编辑:必须计算交点的位置,但是可以通过语言提供的任何方式绘制直线和圆。

输出是n边正多边形的图像,显​​示其工作状态。

图形上对图像大小,格式,线条粗细或此处未提及的其他内容没有任何限制。但是,必须有可能在视觉上区分不同的线,圆及其交点。另外:

  • 构成n形边的n条线必须与“工作”颜色不同(即,任何点,圆或其他线),并且背景颜色也必须再次不同。
  • 工作可以离开绘图区域的边界(点除外),这些点必须全部在图像的可见范围内。
  • 圆可以是一个完整的圆,也可以是一个圆弧(只要它显示所需的相交点即可)。
  • 一条线是无限的(即离开绘图区域),或者在它经过的两个点处被切除。编辑:可以画任何长度的线。只能在绘制的线在视觉上相交的地方创建点。
  • 可以根据需要绘制点,包括不标记点。

评分是双重的,提交支持的每个输入获得1分,最多10分。在平局的情况下,最短的字节数为准。

可以在最少的步骤中构造n-gon或能够在给定范围之外构造n-gon的提交将获得认可,但对您的得分没有帮助。

维基百科的背景信息


如果允许在定义线的点处截断线,则意味着相关的相交点可能在绘制的线之外。
Martin Ender 2014年

如果我们的语言能够提供这样的快捷方式,是否可以通过绘制单个线条ABC来使用绘制两个线段AB和BC之类的快捷方式?
Martin Ender 2014年

1
绘制构造图是否足够,还是程序也必须计算它?例如,如果我想在通过点(300,400)的原点处绘制一个圆,我是否可以(知道半径为500)CIRCLE 0,0,500或者必须做R=SQRT(300^2+400^2): CIRCLE 0,0,R?(顺便说一句,计算交叉路口的位置可能比直线和圆还要困难。)
Level River St

来自维基百科: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
belisarius博士2014年

通常用数学术语将“未标记的标尺”称为“直尺”,例如belisarius的报价。
Justhalf 2014年

Answers:


10

BBC Basic,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

该程序会在要求任何用户输入之前进行预构建。这足以在主圆上定义至少2个点,这些点对应于3、4、5、6、8、10、12、15或60个侧面图形的相邻顶点。这些点存储在一组99个元素的数组中,其中元素0-59放置在圆周上等间距的点上。这主要是为了清楚起见,八边形不能完全适合60个点,因此需要有一定的灵活性(如果包含16个点,还需要一些灵活性)。图像看起来像下面的图像,白色和灰色,仅黄色的两个圆圈专门用于5边倍数的形状。参见http://en.wikipedia.org/wiki/Pentagon#mediaviewer/File:Regular_Pentagon_Inscribed_in_a_Circle_240px.gif我首选的五边形绘制方法。锯齿状的角度是为了避免垂直线,因为程序无法处理无限的渐变。

在此处输入图片说明

用户输入d所需面数的数字。程序在数组中查找两个点中第一个的索引(第二个点沿顺时针方向为60 / d)。

然后,程序循环执行以下过程:绘制一个以第二个点为中心并通过第一个点的圆,并计算新的相交点以使其绕主圆行进。构造圆用蓝色绘制,所需的多边形用红色绘制。最终图像如下所示。

我对他们很满意。BBC Basic足够准确地执行计算。但是,BBC Basic明显(特别是侧面15和60处)的绘制半径往往比应绘制的半径稍小。

在此处输入图片说明


1
我错过的一个技巧是,45度线在两个圆旁边切开主圆,这两个圆可用于构造24边角和40边角,这两个因数均为120。有两个因数60(20和30)缺失,这将需要在预构造中再加一个圆,以定义五边形的两个缺失角,并给出差值1 / 5-1 / 6 = 1/30和1 / 5-1 / 4 = 1/20 。但是,我认为目前我不会更新我的答案。顺便说一句,感谢@Martin的奖金!
级圣河

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以为每种构造选择相关的圆和线。这样,我可以在它们之间重用许多原语。
  • 该代码包含许多样板函数,这些函数确定所有相关的交点,并从两个点创建圆。
  • 有了这个,我将来会添加更多的多边形。

这是未启动的代码:

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

这是输出:

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明


只是想知道为每种输入类型硬编码红色和黑色线条和圆圈并绘制它们是否会更短。
Optimizer

我认为@Optimizer 对于点的n个较大的精确表达式也可能会变得很长。我认为,当我添加更多多边形时,在某个时候为所有多边形制作一个单一的结构,然后在中选择相关的圆形和直线是有意义的Switch。那可能会让我重用更多的圆圈线和点。
Martin Ender 2014年

我这是构建八边形的较短方法,但是我不确定如何向您展示它……
自豪的haskeller 2014年

@proudhaskeller是否更短一点,如果您认为实际上可以放弃结构的前5行是从正方形重新使用代码,并且这种构造方式可能有可能被广义化为从n-gon构造任何2n-gon ?(两件事,我都考虑过要对此加以改进。)如果是这样...嗯...我想用像这样的命名点进行严格的描述是可行的。
Martin Ender 2014年

@proudhaskeller您可以改为在赏金到期之前自行发布。;)
Martin Ender 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.