动画一个旋转的利萨如雕像


15

此项挑战的参赛作品将显示一个动画的旋转的利萨如(Lissajous)人物。3d旋转的出现是因为x参数在每帧中都相移。

输入:

ab参数(按照维基百科文章)将在命令行中指定,或者从stdin读取。

输出:

这是,因此输出将显示在终端仿真器窗口或等效窗口中。输出大小可能是硬编码的,但是Lissajous图形必须至少足够大以填充80x24窗口。

动画帧速率约为50fps。只要计算每帧的时间比固定的睡眠时间短,每帧之间的睡眠时间为20ms就可以了。如果您选择的语言在您选择的平台上无法足够快速地进行计算,那么您将必须动态计算睡眠时间。

在该帧的所有计算完成之前,不会显示每个帧。无需清除每帧之间的屏幕。

该图2*Pi大约每4秒钟旋转一次。

对于每一帧,必须生成完全闭合的曲线。沿曲线至少必须计算1000个点。不需要在点之间画线。

曲线的点将作为#字符绘制。其余显示区域将为空白/空白。

这是,因此,最短答案(以字节为单位)(我认为可以接受)将是在此帖子发布一周后被接受的获胜者。


没有参考的答案


1
我们可以使用面向图形的语言来绘制它吗?
TheDoctor 2014年

@TheDoctor我为此感到痛苦,但是决定限制为ascii-art。如果最终流行的话,也许我们可以进行图形输出跟踪。
Digital Trauma 2014年

1
与许多旋转图形一样,这些图形根据您的外观以不同的方式旋转。例如,您的回答似乎对我来回摇摆。但是当我努力的时候,我可以看到规律的轮换。
贾斯汀

Answers:


7

Perl-177

while($d+=.1){print"\e[H\e[2J";$a=0;while(($a+=.01)<4*atan2 1,0){$x=$==40+40*cos$d+$a*$ARGV[0];$y=$==13+13*sin$d+$a*$ARGV[1];print"\e[$y;$x"."H#";}print$/;select($v,$v,$v,.03);}

系数通过参数传递。上面的gif是从perl % 2 3


1
@DigitalTrauma我有自己的X11录制屏幕工具
mniip 2014年

7

C(参考答案-不打高尔夫球)

输出./lissajous 2 3

在此处输入图片说明

/*
 * lissajous.c
 *
 * Compile with:
 *   cc lissajous.c -lm -o lissajous
 *
 * Usage:
 *   ./lissajous a b
 *
 * a and b are the parameters as described in:
 * http://en.wikipedia.org/wiki/Lissajous_curve
 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <unistd.h>

int main (int argc, char **argv) {
    char buffer[25][80];
    double t, p;
    int x, y;
    int a, b;

    if (argc != 3) return 1;

    a = atoi(argv[1]);
    b = atoi(argv[2]);

    for (;;) {
        for (p = 0; p < 2 * M_PI; p += M_PI / 100) {
            memset(buffer, ' ', sizeof(buffer));
            /* Set 1st char of final line to nul.  Then we can printf
             * the whole 2d array as if it were one long 1d buffer.
             * Line wraps at 80 chars are assumed */
            buffer[24][0] = 0;
            for (t = 0; t < 2 * M_PI; t += M_PI / 500) {
                x = 39.5 * (1 + sin(a * t + p));
                y = 11.5 * (1 + sin(b * t)); 
                buffer[y][x] = '#';
            }
            printf("%s\n", &buffer[0][0]);
            usleep(20000);
        }
    }
    return (0);
}

C,257字节

好吧,好吧,我本人无法抗拒高尔夫。我认为在这方面还有很多事情要做:

#include<math.h>
main(int a,char**v){char x,y,b,d[25][80];double t,p,q=2*M_PI;a=atoi(v[1]);b=atoi(v[2]);for(p=0;memset(d,32,2000);p+=q/100){p=p<q?p:0;d[24][0]=0;for(t=0;t<q;y=11.5*sin(b*t)+12,d[y][x]=35,t+=q/1e3)x=39.5*sin(a*t+p)+40;puts(d);usleep(20000);}}

2
有趣的是参考答案如何获得投票...
TheDoctor 2014年

我知道@TheDoctor,对。这就是为什么我最终添加了一个高尔夫球版本的原因,因为获得不满意的答案是不正确的。
数字创伤

如果要使用usleep20000ms,为什么不只sleep使用20s?
2014年

@ace usleep(20000)== 20000 秒,不20000
数字创伤

糟糕,抱歉,我不好。关于什么usleep(2e4);
user12205 2014年

2

Python 3-280

抱歉,没有这些奇特的gif动画之一。Windows控制台打印速度很慢:P

尽管我不确定Python是否真的可以满足50fps的要求。您可以在第二行上将1000调整为要计算的点数(列表为输出宽度,输出高度,要查找的点,每帧的级数(pi * 2 / n)和起点)。或者,您也可以删除它们并在输入中指定。

import math as m
a,b,w,h,p,r,t=list(map(int,input().split()))+[79,24,1000,100,0]
while 1:v,z=w/2,h/2;d=[[int(m.sin(a*k+t)*v+v),int(m.sin(b*k)*z+z)]for k in[m.pi*2/p*l for l in range(p)]];print('\n'.join(''.join([' ','#'][[i,j]in d]for i in range(w))for j in range(h)));t+=m.pi*2/r

更重要的编辑:通过stdin输入,以空格分隔,换行符终止。将等待您的输入。

编辑:屏幕截图。将此高度更改为40。

李沙育渲染


嗯,它只是在Ubuntu上用python 3.2.3(和2.7.3)挂起。我想我需要从某个地方挖出Windows VM。或学习python。
Digital Trauma

@DigitalTrauma嗯。我正在运行3.3.2。奇怪的是,它不起作用,在我的代码中看不到任何特定于平台的过程。
cjfaure

另存为lissajous.py,然后运行python3 lissajous.py 2 3就足够了吧?
Digital Trauma

@DigitalTrauma哦,哦,对不起。它从而stdin不是args 接收输入(无法指定... oops)。空格分隔。
cjfaure

啊哈-我想我应该已经看到input()并猜到了。现在对3.2.3来说对我来说很好 +1
数字创伤

1

C# - 360 352(跨平台- 332仅适用于Windows)

经过微高尔夫球和四舍五入的错误修复+由Ypnypn建议后编辑

在这个长度上并不是完全有力的竞争者-它几乎完全是参考文献的逐字复制-但是哦。:)

namespace System{class P{static int Main(string[]m){double p=Math.PI*2,a=int.Parse(m[0]),b=int.Parse(m[1]),q,t;for(;;)for(q=0;q<p;q+=p/200){var s=new string(' ',1920).ToCharArray();for(t=0;t<p;t+=p/1000)s[(int)(39.5*Math.Sin(a*t+q)+40)+(int)(11.5*Math.Sin(b*t)+12)*80]='#';Console.SetCursorPosition(0,0);Console.Write(s);Threading.Thread.Sleep(20);}}}}

内存消耗,每次刷新都会创建一个新的数组-最初(重新)使用StringBuilder,但是为了简短起见而牺牲了它。但是至少在我的旧Core2上刷新不到1毫秒。

在删除了一些(现在已经很累了)古老的高尔夫球之后,将其减少了8个字符之后,我尝试通过将其恢复为double而不是int解析,并返回80 * 24而不是1920来使它回到“诗意的” 360。不过,那仍然只有359个-而且我没有想到的其他任何单个字符添加功能确实可以为代码增加任何价值。所以我们只坚持352。:-)

展开(丢失高尔夫球前代码):

namespace System
{
    class P
    {
        static int Main(string[] m)
        {
            double p = Math.PI * 2,
                   a = int.Parse(m[0]),
                   b = int.Parse(m[1]),
                   q, t;

            for (;;)
            {
                for (q = 0; q < p; q += p/200)
                {
                    var s = new string(' ', 1920).ToCharArray();
                    // Alternative - Windows console only:
                    // var s = new char[1920];

                    for (t = 0; t < p; t += p/1000)
                    {
                        s[
                            (int) (39.5*Math.Sin(a * t + q) + 40)
                          + (int) (11.5*Math.Sin(b * t) + 12) * 80
                        ] = '#';
                    }
                    Console.SetCursorPosition(0, 0);
                    Console.Write(s);
                    Threading.Thread.Sleep(20);
                }
            }
        }
    }
}

Windows控制台实际上接受输出许多null字符,从而导致输出(在图形上)与使用实际的空格字符(在图形上)相同-允许少一些字符来初始化字符数组。

没有精美的动画,对不起:-)


Windows控制台实际上接受输出许多null字符。也许这可以解释为什么在Ubuntu上单声道效果不佳。我暂时没有Windows / .net,因此请您相信它可以正常工作。
Digital Trauma 2014年

刚刚添加了一个屏幕截图-应该使其跨平台,但是考虑到它已经具有非竞争者的地位-以及相当“富有诗意”的字符数,也许应该保留原样。:-)
JimmiTh

不需要所有答案都可以是跨平台IMO。如果答案是特定于平台的,则最好提及该平台,尽管C#众所周知,它已经显而易见。
Digital Trauma 2014年

是否using C = Console真的可以拯救任何字符?
Ypnypn

@Ypnypn-入侵系统名称空间后,不会。没有更改或寻找它,因为自我声明的目标是在使用“适当的”字符数组初始化的同时获得相同的360个字符。谢谢。:-)
JimmiTh

1

Python 2.7-214

我想我将再对此进行研究。我觉得这可以进一步降低,但是很难达到Perl字节数。数学似乎是我最大的限制。

警告:可能会损坏您正在使用的任何终端。我在Windows命令提示符下使用进行了测试lissajous.py 2 3。由于可以快速写入命令提示符,因此希望帧跳一点。可以通过srange(s)和中使用更大的值来解决此问题(以速度为代价)t=2*pi*i

我不使用\r\b这里是故意的,因为我正在Windows上运行它,这会花费额外的字符。

from math import*;import sys;a,b=sys.argv[1:];p=s=1920
while p:
 c = [" "]*s
 for i in range(s):
    t=2*pi*i/s;c[int(round((39.5*(1+sin(eval(a)*t+p))))+round(11.5*(1+sin(eval(b)*t)))*80)]="#"
 print ''.join(c)
 p+=.1

+1作品在Ubuntu上,虽然输出是一个有点神经质
数字创伤

@DigitalTrauma是的,跳跃性是由于这是一个跨平台的解决方案(即在Windows命令提示符下工作)引起的。
grovesNL 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.