Yummy1.1尺规作图规范
Yummy1.1兼容Yummy1.0,在此基础上增加了一些功能。
如果还有引起歧义或者无法覆盖所有需求,请评论区回复。
0. 一些格式
本规范不解决描述问题的方法,描述问题仍然需要使用文字语言,但是描述已知条件时请描述清楚位置关系,以及给出的图形的方向。
每行都会产生一个图形,数字k表示第k行产生的图形,虽然并不建议这么使用。
如果该操作得到的图形作为答案或答案的一部分,应该单独成行,并在行末加入;。
;的另一种用法:加在注释前面,表示忽略;后面的内容。注释必须单独成行。
1. 直线Link,-
在Yummy1.1中,为了避免分类讨论,所有直线都被规定了一个方向。
作直线AB的符号是Link(A,B),方向是从A到B,Link(A,B)和Link(B,A) 产生的直线方向相反。
用-来求一个图形的反向,也就意味着Link(A,B)=-Link(B,A)。
接下来你会碰到Link(p,q)的写法,其中p和q是两个圆,则该作法表示两圆心连线。
2. 圆&圆规Cir,Comp,-,@
同样在Yummy1.0中,圆也是有方向的,Cir和Comp操作产生的圆一定是逆时针的。
Cir(A,B)以A为圆心,B为圆上一点作圆。Comp(O,A,B)以O为圆心,AB为半径作圆。- 如果已知一圆
k,则当其强制转化为一个点时,转化为圆心。也可通过@k强制取圆心。
同样地,前加-得到顺时针的圆,如-Comp(A,B,C)。
Q:为什么要有Cir操作?
A:在一些环境下不支持Comp操作,如Euclidea和几何画板。
Q:如何用其他操作代替Comp?
A: 见下方方案(具体食用方法见第4部分)
Comp(O,A,B)=5
a=Cir(O,A)
b=Cir(A,O)
c=Cir(b*a,B)
d=Cir(a*b,B)
Cir(O,c*d);
3. 取点操作Rand,<,&,+,!
前两部分操作都需要点,我们如何创造点呢?
创造点操作可以直接作参数也可以单独成行。需要二次使用的最好单独成行。
3.1 范围界定
- 在某直线上/某圆上可以直接用数字。
- 规定右手手掌展平,手心朝外,大拇指朝图形k的方向,四指指向
<k界定的范围(不包括图形本身)。 - 几个范围用
&隔开时,取这些范围的交。用+隔开时,取这些范围的并。一范围前用!表示取不在该范围的所有点集。 - 特别地,若k是直线,A是一个点,则
k>A表示k*<Link(Rand(<k),A),也就是直线k上从A开始的射线。
Q:为什么没有类似的截取一段圆弧的方法?
*A:个人认为用的不多,可能直接`k<Link(A,B)`方便。**
3.2 随机取点
使用Rand(范围)在指定范围内随机选择一个点。除非范围内所有点都是已知点,否则返回值一定是未知点。
3.3 交点
使用p*q取图形p和图形q的交点。
- 两图形有且仅有一个交点时取这个交点。
- p,q中一条是直线时,从直线上足够远的地方沿直线方向取到第一个交点就是
p*q的值。要取另一个交点(如有),若p是直线则是-p*q,q是直线则p*-q - p,q是相交的两圆时,取在
<Link(p,q)内的交点。相切则取唯一交点。如果要取另一个交点则使用q*p
一种常见的问题:取图形p和图形q异于A的交点。这个问题可以采用p&q&!A取到这个点。
4. 命名,自定义函数与判断=,?
4.1 命名
在Yummy1.1中,图形命名同变量赋值一般,但不需要提前定义。
kkk=Link(B,C)
kkk=Comp(P,B,C)
上面的写法完全合法,最终结果是kkk表示那个圆。
注意,点大写字母开头,其他图形小写字母开头,可以用字母,数字和下划线。
建议之后会用到的图形全部命名,否则会发生将一段代码整体平移后无法使用的情况。
4.2 自定义函数
在Yummy1.1中,函数也可以看做一个一些操作构成的快捷方式。第5节会讲到已有的5个快捷方式。
自定义函数基本格式如下(函数名大写字母开头):
函数名(参数)=行数
你的实现
你的返回值;
我们以5.1中垂线的实现为例:
Bit(A,B)=3
a=Cir(A,B)
b=Cir(B,A)
Link(b*a,a*b);
函数的定义可以递归,但是由于作者本人未尝试过,故不建议这么做。
返回值可以不止一个图形,也可以不全在末尾。只要有分号,调用时都会出现在纸上。
4.3 判断
目前我们只支持点是否在范围内的判断。基本格式如下:
点?范围=点在范围内行数=点不在范围内行数
我们以5.3垂线的实现为例:
Perp(k,A)=9
A?k=4=4
P=Rand(<k)
c=Cir(P,A)
t=Link(P,c&k&!A)
Link(A,t*c);
P=Rand(k)
a=Cir(p,A)
b=Cir(Rand(k>p),A)
Link(b*a,a*b);
5. 快捷操作Bit,Perp,Para,Tang
5.1 中垂线(或垂直平分线)(3步)
Bit(A,B)求以A,B为顶点的线段的角平分线,右手手掌朝纸外,大拇指从A指向B,四指则指向Bit(A,B)的方向。
Q:为什么使用和角平分线一样的名称?
A:bisector既表示平分直线,也可以平分角,而且由于两函数参数不同,故不产生影响。
5.2 角平分线(4步)
Bit(a,b)表示求直线a和直线b的夹角的角平分线。
在a,b相交产生的四个角中,取角两边都是从顶点射出的角。a的方向必须是b的逆时针(看实现就明白了)
求得的角平分线是直线,方向从顶点射出。
Bit(a,b)=2
c=Cir(a*b,Rand())
Bit(a*c,b*c);
5.3 垂线(3步)和平行线(4步)
Perp(k,A)过A点作直线k的垂线。方向指向<k的方向。
Para(k,A)过A点作直线k的平行线。方向与k相同。
Para(k,A)=5
P=Rand(k)
a=Cir(P,A)
b=Cir(k>P,A)
l=Link(P,b*a)
Link(l*a,A);
5.4 切线(圆上3步,圆外5步)
Tang(k,A)过圆k外的一点A作圆k的切线,切点是Link(A,k)*k开始沿圆的方向第一个碰到的可能的切点。方向从A点射出。
实现留做习题。
6. 示例
接下来是Euclidea中一些比较可以体现Yummy1.1语法的题。部分会将其与Yummy1.0对照。 实际上Yummy1.1兼容Yummy1.0,但是添加了一些方便调用的部分。
作者将提供解法。
1.1 60度角(4E)
Yummy1.0: 规定图上点为A,射线0从A射出。(这个0是我们手动定义的,与行数无关,更建议小写字母,或者采用5.1的方法)。
Rand(0)
Cir(A,1)
Cir(1,A)
;这是一行注释
Link(A,2*3);
Link(A,3*2);
第4行和第5行分别对应向上和向下的两条射线。
Yummy1.1:设给定射线为k,顶点为A。显然,这一块作法不管粘贴到哪里都不用修改任何内容。
Deg60(k,A)=5
P=rand(k)
a=Cir(A,P)
b=Cir(P,A)
Link(A,a*b);
Link(A,b*a);
1.7 圆内接正方形(7E)
规定圆z的圆心为O,圆z上一点为A
Square(O,z,A)=7
a=Cir(A,O)
b=Cir(a*z,z*a)
c=Link(a*z,O)
d=Link(-c*b,2*0);
e=Link(A,-d*z);
f=Link(b*c,b*z);
Link(A,z*f);
8.4 正八边形(9L)(咕咕咕)
Rand()
Rand()
Link(1,2);
;第三步产生一条直线,多余部分不用就是了
;下面开始正式解题
Perp(3,1)
Bit(-6,3);
Perp(7,2);
Bit(-3,8)
Perp(7,6*9);
Para(3,6*9);
Para(6,7*9);
Bit(2,8*11);
Para(6,9*13);