我真的很想要菱形,但是我得到的只是这个愚蠢的矩形


33

仅给出一条直尺和一个罗盘,在给定的矩形内刻一个菱形,共享两个相对的点。

矩形菱形

输入项

输入是矩形的尺寸。在所示的示例中,该值为125, 50。您可以采用最方便的方式进行输入(如两个整数,列表,字符串等)。

较大的尺寸最小为100,而较小的尺寸最小为25。两者的上限均为200。

输出量

输出将是图像(显示在屏幕上或保存为文件),显示

  • 输入矩形
  • 所有“工作”线/圆
  • 铭刻的菱形

以不同的颜色。在上图中,矩形为黑色,工作线为蓝色,菱形为橙色。线条应按照列表中显示的顺序绘制(例如菱形覆盖工作线和矩形)。

输出图像必须足够大以包含所有内容。例如,显示的圆圈不能超出范围。

方法

上面的示例图像中使用的方法是:

  • 以左下角为中心,右上角为周长上的点绘制一个圆,其半径等于矩形的对角线。
  • 进行相同的操作,但交换中心点和外围点。
  • 在两个圆的交点之间画一条线,为矩形的对角线提供一个垂直平分线。
  • 使用新线和矩形的交点绘制菱形。

之所以起作用,是因为菱形的内部对角线始终彼此垂直平分。不过,我这里没有提供完整的证明。

这不是获得菱形的唯一方法,并且可以在解释您正在做的事情的同时使用另一种方法。我相信这可能是最简单的。

规则

您只能绘制圆和直线(或直线段)。用中心点和周边点定义一个圆。一条线由任意两点定义。线不必具有任何指定的长度,但是它们必须至少覆盖定义点(请注意示例图像:线稍微越过圆交点,但不越过边缘)。对于圆,从中心到所选周边点的半径被视为一条工作线,必须显示。

要对线条进行栅格化,可以使用任何公认的算法(例如Bresenham算法),也可以依赖于您的语言可能具有的任何内置函数。如果您的输出是基于矢量的,请确保以至少与输入矩形(以像素为单位)一样大的分辨率显示。另外,您将在普通画布上绘画,因此请禁止显示任何网格标记或无关的输出。

别作弊!您只能使用到目前为止建立的内容来确定点/线/圆的位置。如果您无法解释如何使用工作线/圆来显示它是菱形,那说明您做错了。

您可以使用任意一对相对的点,并且只要输出正确,就不需要将矩形绘制为与轴对齐。

输入将始终是非正方形的矩形,因此不必担心会出现特殊情况。

最后,这是标准代码高尔夫,因此以字节为单位的最小大小获胜。


我们是否可以使用数学公式来确定例如绘制圆的交点之间的直线的端点(实际上没有分析图像以查看交点在哪里)?
ETHproductions 2016年

@ETHproductions我会说是的,因为很容易证明它们与半径之间的角度在每一侧均为60度,并且它们形成等边三角形。如果有人有任何异议,我也愿意听到。
Geobits,2016年

3
我们是否可以假设第一个输入大于第二个输入(反之亦然),或者答案必须能够同时处理垂直和水平方向的矩形?
Martin Ender

矩形内短线段的目的是什么?
18Me21 '18

Answers:


11

HTML + JavaScript(ES6),34 + 353 = 387字节

输入应采用格式[125,50]

[w,h]=eval(prompt(c=C.getContext("2d"))).sort();d=q=>(c.strokeStyle=q,b);l=(x,y=Z)=>x?c.lineTo(x,y)||l:c.stroke();b=(x,y=H,r)=>(c.beginPath(),r?c.arc(x,y,Math.sqrt(r),0,2*Math.PI):c.moveTo(x,y),l);b(Z=300,Z)(W=Z+w)(W,H=Z+h)(Z,H)(Z)();d`red`(Z,H,s=w*w+h*h)();b(W,Z,s)();b(Z)(W)();b(Z+w/2-h,Z+h/2-w)(H+w/2,W+h/2)();d`lime`(Z)(W-s/2/w)(W)(Z+s/2/w,H)(Z,H)()
<canvas id=C width=800 height=800>

只是很多数学和绘图...如果高度大于宽度,则矩形是横向绘制的,我认为这是允许的。


哦,比444:P 少10个字节
Kritixi Lithos

@KritixiLithos现在我比400;-) 小10个字节
ETHproductions

当高度大于宽度时,矩形会刻在菱形中。
拉基思(Larkeith)2016年

1
@Larkeith Oops,不知道我们必须解决这些情况。固定为42个字节。
ETHproductions's

您可以使用“的getContext``2D”(无空格),以节省几个字节(为什么他们要使用`和休息降价...)
12Me21

10

数学,157个 148 158字节

感谢Martin Ender以他们一贯的高品质发表评论!在这种情况下,保存9个字节。

一旦明确说明参数可以以任何顺序进行编辑;添加了10个字节以进行补偿。

Graphics@{(m=Line)@{o=0{,},{#,0},c={##},{0,#2},o},Blue,m[l={o,c}],Circle[#,(c.c)^.5]&/@l,m[{k={#2,-#},-k}+{c,c}/2],Red,m@{o,p={0,c.c/2/#2},c,c-p,o}}&@@Sort@#&

再次,这是Mathematica的亮点:涉及数学计算的高级图形输出。相同的代码带有空格和换行符,以提高可读性:

Graphics@{
  (m=Line)@{o = 0{,}, {#, 0}, c = {##}, {0, #2}, o},
  Blue, m[l = {o, c}], Circle[#, (c.c)^.5] & /@ l, 
  m[{k = {#2, -#}, -k} + {c, c}/2],
  Red, m@{o, p = {c.c/2/#2, 0}, c, c - p, o}
} & @@ Sort@# &

单个参数的无名函数,是有序的正数对;最终@@ Sort@# &将这对转换为两个数字参数,其中第一个数字较小。Line产生一个从点到点的多边形路径,如果第一个点和最后一个点相同,它将变成一个封闭的多边形;Circle产生一个具有给定中心和半径的圆。特殊点oc(左下角和右上角矩形角),p(第三个菱形角,由数学公式给出)和k(帮助绘制垂直平分线)在再次调用时会保存字节的方式命名,以及特殊的一对l = {o,c}。Mathematica乐于直接添加点,将两个坐标乘以相同的因子,取其点积等,所有这些都简化了代码。

输出示例,带有参数12550

在此处输入图片说明


1
重新使用不必要的空格。您可以使用此技巧在上保存一个字节{0,0}。由于不需要使用蓝色和橙色,因此可以使用Red代替来保存字节Orange。您使用了Line四次,这足以节省字节i=Line;(作为经验法则,如果表达式包含n字符,并且m您需要使用它的次数(m-1)*(n-1) > 4,那么如果您可以在首次使用时不带括号地分配变量,则可以使用更少的次数)。
马丁·恩德

0{,}把戏真是太棒了:D
格雷格·马丁

如果第二面比第一面长,恐怕这是行不通的。然而,方向并不需要是一致的,所以这可以通过附加固定@@Sort@#&和交换#,并#2在整个代码,或者其适应与人像方向的长方形,而不是工作。
马丁·恩德

是的,这是故意的……似乎我们正在等待澄清是否可以假定尺寸按所需顺序进行。
格雷格·马丁


9

MetaPost,473(有颜色)353(无颜色)

有色(473字节):

A:=170;B:=100;pair X,Y;path C,D,E,F,G,R,T;X=(0,0);Y=(A,B);R=X--(A,0)--Y--(0,B)--cycle;T=(0,B)--(A,B);draw R;E=X--Y;C=X..Y*2..cycle;D=Y..-Y..cycle;F=(D intersectionpoint C)--(C intersectionpoint D);draw C withcolor green;draw D withcolor green;draw E withcolor red;draw F withcolor red;draw (F intersectionpoint R)--Y withcolor blue;draw X--(F intersectionpoint T) withcolor blue;draw (F intersectionpoint T)--Y withcolor blue;draw (F intersectionpoint R)--X withcolor blue;

非彩色(353字节):

A:=170;B:=100;pair X,Y;path C,D,E,F,G,R,T;X=(0,0);Y=(A,B);R=X--(A,0)--Y--(0,B)--cycle;T=(0,B)--(A,B);draw R;E=X--Y;C=X..Y*2..cycle;D=Y..-Y..cycle;F=(D intersectionpoint C)--(C intersectionpoint D);draw C;draw D;draw E;draw F;draw (F intersectionpoint R)--Y;draw X--(F intersectionpoint T);draw (F intersectionpoint T)--Y;draw (F intersectionpoint R)--X;

以前从未使用过它,我敢肯定,我已经将其屠杀了……
但是当您在此网站上运行它时:

http://www.tlhiv.org/mppreview/

它使用圆的交点绘制第二个轴,然后使用该轴和矩形的交点绘制最终的菱形。虽然我可以作弊,只是画一条垂直于第一轴的线哈哈。

要更改尺寸,只需更改A和B。

无论如何,您最终都会得到(对于L = 170,H = 100):

图片


3

Desmos,375(或163)字节

w=125
h=50
\left(wt,\left[0,h\right]\right)
\left(\left[0,w\right],ht\right)
\left(x-\left[0,w\right]\right)^2+\left(y-\left[0,h\right]\right)^2=w^2+h^2
\frac{h}{w}x\left\{0\le x\le w\right\}
-\frac{w}{h}\left(x-\frac{w}{2}\right)+\frac{h}{2}
a=\frac{h^2}{2w}+\frac{w}{2}
\left(t\left(w-a\right)+\left[0,1\right]a,ht\right)
\left(at-\left[0,a-w\right],\left[0,h\right]\right)

wh是输入。在Desmos上尝试!

备用163字节版本:

w=125
h=50
(wt,[0,h])
([0,w],ht)
(x-[0,w])^2+(y-[0,h])^2=w^2+h^2
hx/w\left\{0\le x\le w\right\}
-w(x-w/2)/h+h/2
a=h^2/2/w+w/2
(t(w-a)+[0,1]a,ht)
(at-[0,a-w],[0,h])

此版本要求将每行复制并粘贴到Desmos的每行中。Meta仍然需要确定这是否是一种有效的计数方法,但是前一种方法绝对可以。


这似乎假设输入矩形处于横向,这在任务中未指定。
Henning Makholm '16

1
对我而言,“不需要将矩形绘制为与轴对齐”就意味着矩形上不需要保留任何预定方向,包括横向与纵向。
格雷格·马丁

由于仅给出尺寸(不提供坐标),因此可以根据您的喜好对齐输出,并假定尺寸正确。
Geobits '16

我第一次看到Desmos被用作高尔夫球语言:)
Kritixi Lithos

3

ImageMagick版本7.0.3 + bash + sed,496字节

M=magick
L=$((400-$(($1))/2)),$((400+$(($2))/2))
R=$((400+$(($1))/2)),$((400-$(($2))/2))
Z=" $L $R" Y=" -1 x";D=' -draw' K=' -stroke'
A=' -strokewidth 3 +antialias -fill'
$M xc:[800x]$A none$K \#000$D "rectangle$Z"$D "line$Z"$K \#00F8$D "circle$Z"$K \#0F08$D "circle $R $L" -depth 8 png:a
$M a txt:-|sed "/38C/!d;s/:.*//">x;P=`head$Y`;Q=`tail$Y`
$M a$A \#F008$K \#F008$D "line $P $Q" b
$M b txt:-|sed "/C70/!d;s/:.*//">x;S=`head$Y`;T=`tail$Y`
$M b$A \#F804$K \#F80$D "polyline $L $S $R $T $L" x:

结果为“ rhombus.sh 180 120”

在此处输入图片说明

更精确(使用6400x6400画布而不是800x800),570字节

交点不精确;“ strokewidth”指令使行足够宽,以确保至少一个完整的像素与两条相交线的颜色混合在一起,但是在最坏的情况下(25x200和200x25),交叉处的角度很小,因此云混合像素的长度为几个像素,并且由于我们选择了第一个和最后一个混合像素,因此会出现轻微误差。使用具有相同笔划宽度的大8倍的画布,然后按比例缩小结果,可以将误差减少到小于一个像素,但是大约要花费64倍的时间。

M=magick
L=$((3200-$(($1))*4)),$((3200+$(($2))*4))
R=$((3200+$(($1))*4)),$((3200-$(($2))*4))
K=-stroke;A='-strokewidth 3 +antialias'
$M xc:[6400x] $A -fill none $K \#000 -draw "rectangle $L $R" \
-draw "line $L $R" $K \#00F8 -draw "circle $L $R" \
$K \#0F08 -draw "circle $R $L" -depth 8 png:a 
$M a txt:-|grep 38C077|sed -e "s/:.*//p">x
P=`head -1 x`;Q=`tail -1 x`
$M a $A -fill \#F008 $K \#F008 -draw "line $P $Q" png:b
$M b txt:-|grep C70000|sed -e "s/:.*//p">x
S=`head -1 x`;T=`tail -1 x`
$M b $A -fill \#F804 $K \#F80 -draw "polyline $L $S $R $T $L" -resize 800 x:

普通800x800与精确6400x6400的结果:

正常结果与精确结果

取消高尔夫:

# rhombus.sh
# Inscribe a rhombus in the rectangle with dimensions 2*$1, 2*$2

# Run with "rhombus.sh W H"

M=magick

W=${1:-100};H=${2:-40}

# L locates the lower left corner of the rectangle
L=$((400-$((W))/2)),$((400+$((H))/2))

# R locates the upper right corner of the rectangle
R=$((400+$((W))/2)),$((400-$((H))/2))

# We'll need this several times
A='-strokewidth 3 +antialias'

# Establish 800x800 canvas (white) (circles + rectangle will
# always fit in 764x764)
#
# Draw the W x H rectangle (black) in center of canvas
#
# Draw two circles (blue, 50% alpha [#00F8] and green, 50% alpha [#0F08])
#  one centered at point L with peripheral point R
#  the other centered at point R with peripheral point L

$M xc:[800x] $A -fill none \
       -stroke \#000  -draw "rectangle $L $R" \
                      -draw "line      $L $R" \
       -stroke \#00F8 -draw "circle    $L $R" \
       -stroke \#0F08 -draw "circle    $R $L" \
       -depth 8 a.png 

# Find P and Q, the 2 intersections of the circles,
# that have mixed color #38C077 
$M a.png txt:-|grep 38C077|sed -e "s/:.*//p">x
P=`head -1 x`;Q=`tail -1 x`

# Draw line connecting the intersections P and Q
$M a.png $A -fill \#F008 -stroke \#F008 -draw "line $P $Q" b.png

# Find S and T, the 2 intersections of the line with the original rectangle,
# that have mixed color #C70000
$M b.png txt:-|grep C70000|sed -e "s/:.*//p">x
S=`head -1 x`;T=`tail -1 x`

# Draw the rhombus
$M b.png $A -fill \#F804 -stroke \#F80 -draw "polyline $L $S $R $T $L" d.png

我喜欢您检测交叉点的方式,非常好。最后的混色正确吗?我问,因为看起来菱形和矩形线略有偏离。我认为可能是由于抗锯齿(可能还有笔触宽度)而在稍微偏僻的地方检测到了颜色。
Geobits '16

2

R,290字节

function(A,B,p=polygon){R=A^2+B^2
D=2*A
a=sqrt(R)*cbind(cos(t<-seq(0,2*pi,.01)),sin(t))
b=t(t(a)+c(A,B))
x=range(a,b)
plot(NA,xli=x,yli=x,as=1,ax=F,an=F)
rect(0,0,A,B)
segments(0,0,A,B,c=4)
p(a,b=4)
p(b,b=4)
curve(B/2-A*x/B+A^2/2/B,co=4,a=T)
p(cbind(c((R-2*B^2)/D,A,R/D,0),c(B,B,0,0)),b=3)}

匿名功能,输出显示在屏幕上。略有偏离,并带有注释:

function(A,B){
    R=A^2+B^2
    D=2*A
    t=seq(0,2*pi,.01)
    a=sqrt(R)*cbind(cos(t),sin(t)) #Circle with (0,0) as center
    b=t(t(a)+c(A,B)) #Second circle transposed to (A,B) center
    x=range(a,b)
    #Empty plot, large enough to fit the 2 circles:
    plot(NA,xlim=x,ylim=x,asp=1,axes=F,ann=F)
    rect(0,0,A,B) #Initial rectangle
    segments(0,0,A,B,col=4) #Rectangle diagonal
    polygon(a,border=4) #Circle 1 (border is b thanks to partial matching)
    polygon(b,border=4) #Circle 2
    curve(B/2-A*x/B+A^2/2/B,col=4,add=T) #Line joining circles intersection
    polygon(cbind(c((R-2*B^2)/D,A,R/D,0),c(B,B,0,0)),border=3) #Rhombus
}

(120,100)的示例输出:

在此处输入图片说明


2

LibreLogo,270个字节

用户输入被视为一个数组:[width, height][height, width]

码:

fc [24]
D=180
R=sorted(eval(input "))
W=R[1]
H=R[0]
L=sqrt W**2+H**2
A=D/π*asin(H/L)
Z=A*2
S=L/2/cos A*π/D rectangle[W,H]pc 255 lt A fd 400 bk 800 fd 400 rt A pu bk H/2 lt 90 fd W/2 pd circle L*2 rt D-A fd L circle L*2 pc [5]lt D-A fd S lt Z fd S rt D+Z fd S lt Z fd S

结果:

在此处输入图片说明

说明:

fc [24]                        ; Fill Color = Invisible
D = 180                        ; D = 180° (Saved Bytes)
R = sorted( eval( input " ) )  ; R = Sorted Array of Rectangle Width and Height (User Input)
W = R[1]                       ; W = Rectangle Width
H = R[0]                       ; H = Rectangle Height
L = sqrt W**2 + H**2           ; L = Rectangle Diagonal Length
A = D / π * asin( H / L )      ; A = Rectangle Diagonal Angle°
Z = A * 2                      ; Z = Rectangle Diagonal Angle° * 2 (Saved Bytes)
S = L / 2 / cos A * π / D      ; S = Rhombus Side Length
rectangle [W, H]               ; Draw Rectangle
pc 255                         ; Pen Color = Blue
lt A                           ; Left = Rectangle Diagonal Angle°
fd 400                         ; Forward = 400 pt
bk 800                         ; Back = 800 pt
fd 400                         ; Forward = 400 pt
rt A                           ; Right = Rectangle Diagonal Angle°
pu                             ; Pen Up
bk H / 2                       ; Back = Rectangle Height / 2
lt 90                          ; Left = 90°
fd W / 2                       ; Forward = Rectangle Width / 2
pd                             ; Pen Down
circle L * 2                   ; Draw Left Circle (Radius = Rectangle Diagonal Length)
rt D - A                       ; Right = 180° - Rectangle Diagonal Angle°
fd L                           ; Forward = Rectangle Diagonal Length
circle L * 2                   ; Draw Right Circle (Radius = Rectangle Diagonal Length)
pc [5]                         ; Pen Color = Red
lt D - A                       ; Left = 180° - Rectangle Diagonal Angle°
fd S                           ; Forward = Rhombus Side Length
lt Z                           ; Left = Rectangle Diagonal Angle° * 2
fd S                           ; Forward = Rhombus Side Length
rt D + Z                       ; Right = 180° + Rectangle Diagonal Angle° * 2
fd S                           ; Forward = Rhombus Side Length
lt Z                           ; Left = Rectangle Diagonal Angle° * 2
fd S                           ; Forward = Rhombus Side Length

1

Python 3.5 + Tkinter,433或515字节

非彩色(433字节):

from tkinter import*
def V(a,b):S=500;Y,Z=S+a,S-b;M=(a**2+b**2)**0.5;D=Tk();C=Canvas(D);B=C.create_oval;X=C.create_line;B(S+M,S-M,S-M,S+M);B(Y-M,Z+M,Y+M,Z-M);X(Y,Z,S,S);C.create_rectangle(Y,S,S,Z);Q=-((Z-S)/(Y-S))**-1;U,V=(Y+S)/2,(Z+S)/2;X(U+M,V+M*Q,U-M,V-M*Q);P=[(Y,Q*(Y-U)+V),(((Z-V)/Q)+U,Z)][a>b];L=[(S,Q*(S-U)+V),(((S-V)/Q)+U,S)][a>b];X(S,S,P[0],P[1]);X(Y,Z,P[0],P[1]);X(Y,Z,L[0],L[1]);X(S,S,L[0],L[1]);C.pack(fill=BOTH,expand=1)

有色(515字节):

from tkinter import*
def V(a,b):S=500;t='blue';Y,Z=S+a,S-b;M=(a**2+b**2)**0.5;D=Tk();C=Canvas(D);B=C.create_oval;X=C.create_line;B(S+M,S-M,S-M,S+M,outline=t);B(Y-M,Z+M,Y+M,Z-M,outline=t);X(Y,Z,S,S,fill=t);C.create_rectangle(Y,S,S,Z);Q=-((Z-S)/(Y-S))**-1;U,V=(Y+S)/2,(Z+S)/2;X(U+M,V+M*Q,U-M,V-M*Q,fill=t);P=[(Y,Q*(Y-U)+V),(((Z-V)/Q)+U,Z)][a>b];L=[(S,Q*(S-U)+V),(((S-V)/Q)+U,S)][a>b];o='orange';X(S,S,P[0],P[1],fill=o);X(Y,Z,P[0],P[1],fill=o);X(Y,Z,L[0],L[1],fill=o);X(S,S,L[0],L[1],fill=o);C.pack(fill=BOTH,expand=1)

将输入作为2个逗号分隔数字的命名函数。输出在单独的窗口中给出,您可能需要调整窗口大小才能查看完整的输出。这是以下示例的彩色输出V(180,130)

样本输出


0

SmileBASIC,280个字节

INPUT W,H
W=MAX(W,H)/4H=MIN(W,H)/4D=SQR(W*W+H*H)N=D+W
M+D+H
GBOX D,D,N,M,#RED
GCIRCLE D,M,D
GCIRCLE N,D,D
GLINE D,M,N,D
X=D+W/2Y=D+H/2A=ATAN(W,H)E=D*H/W/2S=E*COS(A)T=E*SIN(A)GLINE X-S*9,Y-T*9,X+S*9,Y+T*9GCOLOR-#L
GLINE D,M,X-S,Y-T
GLINE D,M,X+S,M
GLINE N,D,X+S,Y+T
GLINE N,D,X-S,D

(屏幕截图/说明将很快发布)背景颜色为黑色,矩形为红色,圆圈和线条为白色,菱形为黄色。

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.