Làm sinh động một hình Lissajous quay


15

Bài dự thi cho thử thách này sẽ hiển thị một nhân vật Lissajous xoay hoạt hình . Sự xuất hiện của xoay 3d xảy ra khi tham số x được dịch pha liên tiếp trong mỗi khung.

Đầu vào:

Các tham số ab(theo bài viết trên wikipedia ) sẽ được chỉ định tại dòng lệnh hoặc đọc từ stdin.

Đầu ra:

Đây là , vì vậy đầu ra sẽ được hiển thị trong cửa sổ giả lập thiết bị đầu cuối hoặc tương đương. Kích thước đầu ra có thể được mã hóa cứng, nhưng con số Lissajous ít nhất phải đủ lớn để lấp đầy cửa sổ 80x24.

Tốc độ khung hình hoạt hình sẽ xấp xỉ 50 khung hình / giây. Ngủ trong 20ms giữa mỗi khung là tốt, miễn là thời gian để tính toán từng khung là nhỏ so với thời gian ngủ cố định. Nếu lựa chọn ngôn ngữ của bạn không thể tính toán đủ nhanh trên nền tảng bạn đã chọn, thì bạn sẽ phải tính toán thời gian để ngủ một cách linh hoạt.

Mỗi khung sẽ không được hiển thị cho đến khi tất cả tính toán cho khung đó hoàn tất. Không cần phải xóa màn hình giữa mỗi khung.

Con số sẽ thực hiện một 2*Pivòng quay đầy đủ khoảng 4 giây một lần.

Đối với mỗi khung, một đường cong kín hoàn toàn phải được tạo ra. Ít nhất 1000 điểm phải được tính dọc theo đường cong. Vẽ đường thẳng giữa các điểm là không cần thiết.

Điểm của đường cong sẽ được vẽ dưới dạng #ký tự. Phần còn lại của khu vực hiển thị sẽ trống / khoảng trắng.

Đây là , vì vậy câu trả lời ngắn nhất tính bằng byte (được tôi coi là chấp nhận được) sẽ là người chiến thắng được chấp nhận một tuần sau khi đăng bài này.


Ungolfed trả lời tham khảo .


1
Chúng ta có được phép vẽ nó bằng ngôn ngữ hướng đồ họa không?
TheDoctor

@TheDoctor Tôi đã bị rách về điều đó, nhưng đã quyết định hạn chế ascii-art . Có lẽ chúng ta có thể thực hiện theo dõi đầu ra đồ họa nếu điều này kết thúc phổ biến.
Chấn thương kỹ thuật số

1
Cũng như nhiều hình xoay, những hình này xoay theo nhiều cách khác nhau tùy thuộc vào cách bạn nhìn vào chúng. Ví dụ, câu trả lời của bạn dường như đang rung chuyển trở lại với tôi. Nhưng khi tôi cố gắng hết sức, tôi có thể thấy vòng quay đều đặn.
Justin

Câu trả lời:


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);}

Các hệ số được truyền qua các đối số. Các gif trên được sản xuất từperl % 2 3


1
@DigitalTrauma Tôi có công cụ riêng để ghi lại màn hình trong X11
mniip

7

C (câu trả lời tham khảo - không chơi gôn)

Đầu ra với ./lissajous 2 3:

nhập mô tả hình ảnh ở đây

/*
 * 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 byte

Ok, tôi không thể cưỡng lại việc chơi golf một chút. Tôi nghĩ rằng có rất nhiều golf để được thực hiện về điều này mặc dù:

#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
thật buồn cười khi câu trả lời tham khảo đang được nâng cấp ...
TheDoctor

@TheDoctor Tôi biết, đúng rồi. Đó là lý do tại sao tôi đã kết thúc việc thêm một phiên bản chơi gôn, vì cảm thấy không đúng khi nhận được những câu trả lời cho câu trả lời không có căn cứ.
Chấn thương kỹ thuật số

Nếu bạn đang sử usleepdụng 20000ms, tại sao không chỉ sleeptrong 20 giây?
dùng12205

@ace us ngủ (20000) == 20000 micro giây, không phải 20000 milli giây
Chấn thương kỹ thuật số

Rất tiếc, xin lỗi, xấu của tôi. Thế còn usleep(2e4);?
dùng12205

2

Con trăn 3 - 280

Đừng có một trong những gif hoạt hình lạ mắt cho bạn, xin lỗi. Bảng điều khiển Windows chậm in: P

Không chắc điều này đáp ứng yêu cầu 50fps mặc dù tôi không chắc nó thực sự khả thi với Python. Bạn có thể điều chỉnh 1000 trên dòng thứ hai để tính số điểm cần tính (danh sách là chiều rộng đầu ra, chiều cao đầu ra, điểm cần tìm, tiến trình trên mỗi khung (pi * 2 / n) và điểm bắt đầu). Hoặc bạn có thể loại bỏ chúng và chỉ định trong đầu vào là tốt.

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

EDIT QUAN TRỌNG THÊM: Đầu vào thông qua stdin, phân tách không gian, dòng mới kết thúc. Sẽ chờ đầu vào của bạn.

EDIT: Ảnh chụp màn hình. Thay đổi chiều cao thành 40 cho cái này.

Lissajous render


Hmm, nó chỉ treo cho tôi với python 3.2.3 (và 2.7.3) trên Ubuntu. Tôi đoán tôi cần phải đào một máy ảo Windows từ đâu đó. Hoặc học trăn.
Chấn thương kỹ thuật số

@DigitalTrauma Hừm. Tôi đang chạy 3.3.2. Điều kỳ lạ là nó không hoạt động mặc dù, không thấy bất kỳ quy trình cụ thể nền tảng nào trong mã của tôi.
cjfaure

Lưu như là lissajous.py, sau đó chạy python3 lissajous.py 2 3là đủ, phải không?
Chấn thương kỹ thuật số

@DigitalTrauma ơi, xin lỗi. Nó lấy đầu vào từ stdin, không phải các đối số (không thể xác định rằng ... rất tiếc). Không gian ngăn cách.
cjfaure

Aha - Tôi đoán tôi nên đã thấy input()và đoán điều đó. Bây giờ làm việc tốt với tôi với 3.2.3. +1
Chấn thương kỹ thuật số

1

C # - 360 352 (đa nền tảng - chỉ dành cho Windows)

Đã chỉnh sửa sau khi sửa lỗi vi mô và làm tròn lỗi + đề xuất của Ypnypn

Không chính xác là một ứng cử viên ở độ dài đó - và đó gần như là một bản sao nguyên văn của tài liệu tham khảo - nhưng ồ. :)

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);}}}}

Bộ nhớ hog, tạo ra một mảng mới cho mỗi lần làm mới - ban đầu (lại) đã sử dụng StringBuilder, nhưng đã hy sinh nó trong thời gian ngắn. Nhưng ít nhất việc làm mới chỉ mất chưa đến 1 ms trên Core2 cũ của tôi.

Sau khi loại bỏ một số môn đánh gôn cũ - giờ đã gây tổn thương - bằng cách giảm 8 ký tự, tôi đã cố gắng đưa nó trở lại 360 "thơ mộng" bằng cách quay lại gấp đôi thay vì phân tích cú pháp và quay lại 80 * 24 thay vì 1920. Tuy nhiên, đó vẫn chỉ là 359 - và không có sự bổ sung nhân vật nào khác mà tôi có thể nghĩ đến thực sự bổ sung bất kỳ giá trị nào vào mã. Vì vậy, chúng tôi sẽ chỉ gắn bó với 352. :-)

Không được kiểm soát (mất mã tiền golf):

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);
                }
            }
        }
    }
}

Bảng điều khiển Windows thực sự chấp nhận xuất ra rất nhiều ký tự null dẫn đến kết quả đầu ra (về mặt đồ họa) giống hệt với việc sử dụng một ký tự không gian thực tế - cho phép ít hơn một vài ký tự để khởi tạo mảng ký tự.

Không có hoạt hình ưa thích, xin lỗi :-)


Bảng điều khiển Windows thực sự chấp nhận xuất ra rất nhiều ký tự null . Có lẽ điều đó giải thích tại sao nó không tốt với mono trên Ubuntu. Tôi không có windows / .net tiện dụng ngay bây giờ, vì vậy tôi sẽ tin bạn rằng nó hoạt động.
Chấn thương kỹ thuật số

Chỉ cần thêm một ảnh chụp màn hình - sẽ làm cho nó đa nền tảng, nhưng xem xét trạng thái không phải là đối thủ mà nó đã có - và số lượng ký tự khá "thơ mộng", có lẽ nó nên được giữ nguyên. :-)
JimmiTh

Không cần tất cả các câu trả lời là IMO đa nền tảng. Nếu câu trả lời là dành riêng cho nền tảng, thật tốt khi đề cập đến nền tảng, mặc dù C # nổi tiếng đến mức nó đã rõ ràng.
Chấn thương kỹ thuật số

using C = Consolethực sự cứu bất kỳ nhân vật?
Ypnypn

@Ypnypn - không phải sau khi xâm chiếm không gian tên Hệ thống, không. Không thay đổi nó, hoặc tìm kiếm nó, bởi vì mục tiêu tự nêu là để có cùng 360 ký tự trong khi vẫn sử dụng khởi tạo mảng char "phù hợp". Cảm ơn. :-)
JimmiTh

1

Con trăn 2.7 - 214

Tôi nghĩ rằng tôi sẽ có cái nhìn khác về điều này. Tôi có cảm giác điều này có thể được đưa xuống hơn nữa, nhưng sẽ rất khó để đạt được số byte Perl. Toán học dường như là hạn chế lớn nhất của tôi ở đây.

Cảnh báo: có thể sập bất cứ thiết bị đầu cuối nào bạn đang sử dụng. Tôi đã thử nghiệm điều này trên dấu nhắc lệnh của Windows với lissajous.py 2 3. Bởi vì viết nhanh đến dấu nhắc lệnh, hy vọng các khung sẽ nhảy một chút. Điều này có thể được giải quyết chủ yếu (với chi phí tốc độ) bằng cách sử dụng số lớn hơn strong range(s)t=2*pi*i.

Tôi không sử dụng \rhoặc \bở đây một cách có chủ đích vì tôi đang chạy nó trên Windows và nó sẽ tốn thêm các ký tự.

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 Hoạt động trên Ubuntu, mặc dù đầu ra hơi khó khăn
Chấn thương kỹ thuật số

@DigitalTrauma Vâng, sự tăng vọt được gây ra bởi đây là một giải pháp đa nền tảng (nghĩa là để làm việc trên dấu nhắc lệnh của Windows).
GrovesNL
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.