画一条直线


15

绘制包含直线的简单ASCII艺术图像。它类似于这个这个,但不同的规格。

输入值

您可以修改此输入格式以适合您的代码。

  • 整数 width
  • 整数 height
  • 整数 x0
  • 整数 y0
  • 整数 x1
  • 整数 y1

输出量

填充的ASCII艺术图像,具有指定的宽度和高度,其中包含一条从像素(x0, y0)到像素的线(x1, y1)

任何标准形式的文本输出都是可以接受的,但不要使用内置的线条绘制功能。

细节

该线条必须使用单个可打印字符(例如#)绘制,而背景则用不同的字符(例如.)填充。您必须打印必要的结尾字符,以便图像尺寸正确。

像素坐标可以是0索引或1索引,并且可以从图像的任何角落开始。应通过想象一条连接起始像素和终止像素中心的0宽度子像素线来绘制该线。该行输入的每个像素均应填写。

获奖

通常的代码高尔夫球规则。最短的代码获胜。

例子

IN: width, height, x0, y0, x1, y1

IN: 7, 6, 0, 0, 6, 5
OUT:
.....##
....##.
...##..
..##...
.##....
##.....

IN: 3, 3, 1, 1, 1, 1
OUT:
...
.#.
...

IN: 3, 3, 0, 2, 2, 0
OUT:
#..
.#.
..#

IN: 6, 3, 0, 0, 5, 2
OUT:
....##
.####.
##....

IN: 4, 4, -1, -1, 0, 3
OUT:
#...
#...
#...
....

4
我会说“欢迎使用PPCG”,但是您在这里注册的时间几乎与我一样长。:-)不错的第一个挑战!
AdmBorkBork

我们可以输出实际的点而不是空格吗?或除空格以外的其他任何字符?(假设仍包含尾随的<character>)
Rɪ1717年

当然!我将进行编辑
Curtis Bechtel

1
@AlbertRenshaw实际上,当我在Wikipedia上查看Curve时,它指出:“ 在数学上,曲线( 通常在较早的文章中也称为曲线 )是类似于 直线的对象,但不一定是直线。 ” )
Kevin Cruijssen

1
@KevinCruijssen暗示直线 需要直线,不是吗?;)
Albert Renshaw

Answers:


2

Mathematica,166137字节

l:={i,j};s=Sign;f[p_,q_,h_,w_]:=Grid@Table[(1-Max[s[p-l]s[q-l],0])Boole[Abs@Mean[s@Det@{p-l+#,p-q}&/@Tuples[.5{1,-1},2]]<.6],{i,h},{j,w}]

更具可读性的版本:

l := {i, j}; s = Sign; 
f[p_, q_, h_, w_] := 
 Grid@Table[(1 - Max[s[p - l] s[q - l], 0]) Boole[
     Abs@Mean[
        s@Det@{p - l + #, p - q} & /@ 
         Tuples[.5 {1, -1}, 2]] < .6], {i, h}, {j, w}]

这定义了一个名为的函数f。我相当自由地解释了输入和输出规范。该函数f以格式输入f[{x0, y0}, {x1, y1}, height, width],并且网格从左上角开始为1索引。输出看起来像

样本输出

该行显示为1s,背景显示为0s(此处显示f[{2, 6}, {4, 2}, 5, 7])。转弯的数学矩阵的任务1S和0s转换的字符串#S和.S在许多其他挑战已经golfed之前,所以我可以只使用一个标准的方法,但我不认为增加了什么有趣的事。

说明:

一般的想法是,如果线穿过某个像素,则该像素的四个角中的至少一个在该线上方,而至少一个在其下方。我们通过检查向量({x0,y0}至)和({x0,y0}{x1,y1})之间的角度来检查拐角是在直线上方还是下方:如果该角度为正,则拐角位于上方;如果角度为负,则拐角位于下方。

如果我们有两个向量{a1,b1}{a2,b2},则可以通过找到矩阵行列式的符号来检查它们之间的夹角是正还是负{{a1,b1},{a2,b2}}。(我的旧方法是使用复数算法,这太复杂了……嗯,很复杂。)

在代码中的工作方式如下:

  • {p-l+#,p-q}&/@Tuples[.5{1,-1},2]会从四个矢量{x0,y0}和像素的四个角(带l:={i,j},所述像素的坐标,前面所定义的),并且还之间的矢量{x0,y0}{x1,y1}
  • s@Det@...查找直线和四个角之间的角度符号(使用s=Sign)。这些将等于-1、0或1。
  • Abs@Mean[...]<.6检查某些角度为正,某些角度为负。具有此属性的4个符号的均值的均值在-0.5到0.5(含)之间,因此我们将其与0.6进行比较,以使用<代替来保存一个字节<=

仍然存在一个问题:此代码假定直线永远在两个方向上延伸。因此,我们需要通过乘以1-Max[s[p-l]s[q-l],0](通过反复试验得出)来裁剪线1,该线位于线的端点定义的矩形之内和0之外。

用矩形裁剪一条线

其余的代码组成了这些像素的网格。

(此外,这是更早的尝试,使用了完全不同的方法,为181个字节:)

Quiet@Grid@Table[(1-Max[Sign[{i,j}-#3]Sign[{i,j}-#4],0])Boole[#3==#4=={i,j}||2Abs@Tr[Cross@@Thread@{{i,j},#3,#4}]/Norm[d=#3-#4]<2^.5Cos@Abs[Pi/4-Mod[ArcTan@@d,Pi/2]]],{i,#},{j,#2}]&

1
到此为止,该吃午饭了!(在6:30 pm…)
不是一棵树

1

CJam,122个字节

{),V>{[I\]E.*A.+}/}:F;l~]2/~@:S~'.*f*\@:A.-_:g:E;:z:D[0=:B{D~I2*)*+:U(2/B/FU2/B/:V;}fID~\:I;F]{_Wf>\S.<+:*},{~_3$=@0tt}/N*

在线尝试

这基本上结合 我先前为其他挑战而写的两个答案(主要是第二个函数的计算l)。
(0,0)自然是左上角,而不是语句中的示例的左下角。

概述:

{),V>{[I\]E.*A.+}/}:F;定义函数f,这有助于产生所有像素(坐标对),用于一个给定的x坐标
l~]2/~@:S~'.*f*\@:A.-_:g:E;:z:D读取并处理所述输入,并创建点的矩阵
0=:B{D~I2*)*+:U(2/B/FU2/B/:V;}fI迭代除了最后一个所有的x坐标,并且生成所有对应像素
D~\:I;F确实为同一最后一个x坐标
{_Wf>\S.<+:*},仅保留应显示在图像内部的像素,
{~_3$=@0tt}/将0放入矩阵中,每个像素
N*将矩阵与换行符一起显示

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.