Dönen Lissajous Figürüne Animasyon Yap


15

Bu meydan okuma için girişler hareketli bir dönen Lissajous figürü gösterecektir . 3B rotasyonun görünümü, x parametresi her bir karede art arda faz kaymasıyla ortaya çıkar.

Giriş:

aVe bparametreler (uyarınca wikipedia makalesinde ) komut satırına belirtilmemişse veya stdin'den okunacaktır.

Çıktı:

Bu , bu nedenle çıktı bir terminal emülatör penceresinde veya eşdeğerinde görüntülenir. Çıktı boyutu sabit kodlanmış olabilir, ancak Lissajous figürü en az 80x24 pencereyi dolduracak kadar büyük olmalıdır.

Animasyon kare hızı yaklaşık 50 fps olacaktır. Her karenin hesaplanması için gereken süre, sabit uyku süresine kıyasla küçük olduğu sürece, her kare arasında 20 ms uyumak iyidir. Dil seçiminiz seçtiğiniz platformda yeterince hızlı hesaplanamıyorsa, dinamik olarak uyku zamanını hesaplamanız gerekir.

Her bir kare için tüm hesaplama tamamlanıncaya kadar her kare gösterilmez. Her kare arasındaki ekranı temizlemeye gerek yoktur.

Şekil 2*Piyaklaşık her 4 saniyede bir tam dönüş yapacak .

Her kare için tam kapalı bir eğri oluşturulmalıdır. Eğri boyunca en az 1000 nokta hesaplanmalıdır. Noktalar arasında çizgi çizmeye gerek yoktur.

Eğrinin noktaları #karakter olarak çizilecektir . Görüntüleme alanının geri kalanı boş / beyaz olacaktır.

Bu , bu yüzden bayt cinsinden en kısa cevap (benim tarafımdan kabul edilebilir kabul edilir), bu gönderiden bir hafta sonra kabul edilen kazanan olacaktır.


Yanıtlanmamış referans yanıtı .


1
Grafik odaklı bir dil kullanarak çizmemize izin var mı?
TheDoctor

@TheDoctor Ben bu konuda yırtılmış, ancak ascii-sanat ile sınırlamaya karar verdim . Belki de bu popüler hale gelirse bir grafik çıktı takibi yapabiliriz .
Dijital Travma

1
Birçok dönen figürde olduğu gibi, bu şekiller onlara nasıl baktığınıza bağlı olarak farklı yollar döndürür. Örneğin, cevabınız bana ileri geri sallanıyor gibi görünüyor. Ama çok denediğimde, düzenli dönmeyi görebiliyorum.
Justin

Yanıtlar:


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

Katsayılar argümanlar üzerinden iletilir. Yukarıdaki gifperl % 2 3


1
@DigitalTrauma X11'de ekran kaydetmek için kendi aracım var
mniip

7

C (referans yanıtı - golf değil)

Çıktı ./lissajous 2 3:

resim açıklamasını buraya girin

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

Tamam, biraz golf oynamaya dayanamadım. Bence bu konuda yapılacak çok daha fazla golf var:

#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
komik nasıl referans cevap ... upvotes oluyor
TheDoctor

@Doktor biliyorum, doğru. Bu yüzden golf edilmemiş bir cevap ekledim.
Dijital Travma

Eğer usleep20000ms için arıyorsanız, neden sadece sleep20s için değil ?
user12205

@ace usleep (20000) == 20000 mikro saniye, 20000 mili saniye değil
Dijital Travma

Hata, özür dilerim. Ne olmuş usleep(2e4);?
user12205

2

Python 3-280

Üzgünüm, senin için bu fantezi animasyonlu giflerden birine sahip değilsin. Windows konsolu yazdırmada yavaş: P

Python ile gerçekten mümkün olduğundan emin değilim ama bunun 50fps gereksinimini karşıladığından emin değilim. 1000'i ikinci satırda hesaplanacak nokta miktarı için ayarlayabilirsiniz (liste çıktı genişliği, çıktı yüksekliği, bulunacak noktalar, kare başına ilerleme (pi * 2 / n) ve başlangıç ​​noktasıdır). Veya bunları kaldırabilir ve girişte de belirtebilirsiniz.

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

DAHA FAZLA ÖNEMLİ DÜZENLEME: stdin, boşlukla ayrılmış, satırsonu ile giriş. Girişinizi bekleyecek.

EDIT: Ekran görüntüsü. Bunun için yükseklik 40 olarak değiştirildi.

Lissajous oluşturma


Hmm, sadece Ubuntu'da python 3.2.3 (ve 2.7.3) ile takılıyor. Sanırım bir yerden bir Windows VM kazmalıyım. Veya python öğrenin.
Dijital Travma

@DigitalTrauma Hm. 3.3.2 koşuyorum. Yine de işe yaramadığı garip, kodumda platforma özel prosedürler görmüyorum.
cjfaure

Farklı kaydet lissajous.py, sonra çalıştır python3 lissajous.py 2 3yeterli olmalı, değil mi?
Dijital Travma

@DigitalTrauma Oh, oh, üzgünüm. Değişkenlerden stdindeğil girdi alır (bunu belirleyemedi ... oops). Uzay-ayrıldı.
cjfaure

Aha - Sanırım görmeli input()ve tahmin etmeliydim . 3.2.3 ile benim için iyi çalışıyor. +1
Dijital Travma

1

C # - 360 352 (çapraz platform - Windows için 332 için)

Ypnypn tarafından mikro golf ve yuvarlama hata düzeltmesi + öneri sonrasında düzenlendi

Tam olarak bu uzunlukta bir yarışmacı değil - ve referansın kelimesi kelimesine bir kopyası - ama oh iyi. :)

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

Hafıza domuz, her yenileme için yeni bir dizi oluşturma - başlangıçta bir StringBuilder (yeniden) kullandı, ancak kısalık için kurban etti. Ancak en azından yenileme eski Core2 cihazımda 1 ms'den daha az sürüyor.

Biraz - şimdi uzun yaralı - eski golf kaldırdıktan sonra 8 karakter azaltarak, int ayrıştırma yerine iki katına dönerek ve 1920 yerine 80 * 24 dönerek "şiirsel" 360 geri almaya çalıştım. Bu hala sadece 359, - ve düşünebileceğim başka hiçbir tek karakter ek gerçekten koda herhangi bir değer katıyor. 352 ile devam edeceğiz. :-)

Unrolled (golf öncesi kodunu kaybetti):

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 konsolu, gerçek bir boşluk karakteri (grafiksel olarak) ile aynı olan ve karakter dizisini başlatmak için birkaç karakterin daha az olmasını sağlayan çok sayıda boş karakter çıktısını kabul eder.

Süslü animasyon yok, üzgünüm :-)


Windows konsolu aslında çok sayıda boş karakter çıkarmayı kabul eder . Ah belki de bu Ubuntu'da mono ile neden bu kadar iyi olmadığını açıklıyor. Şu anda windows / .net kullanmıyorum, bu yüzden işe yaradığını söyleyeceğim.
Dijital Travma

Sadece bir ekran görüntüsü ekledi - çapraz platform yapmalı, ancak zaten rakip olmayan durumu ve oldukça "şiirsel" karakter sayısı göz önüne alındığında, belki de olduğu gibi bırakılmalıdır. :-)
JimmiTh

Tüm yanıtların platformlar arası IMO olması gerekmez. Yanıtlar platforma özgü ise, platformdan bahsetmek güzel, ancak C # çok iyi biliniyor, zaten açık.
Dijital Travma

Does using C = Consolegerçekten herhangi karakterleri kaydetmek?
Ypnypn

@Ypnypn - Sistem ad alanını işgal ettikten sonra değil, hayır. Bunu değiştirmedim, ya da aramadın, çünkü kendi belirlediği hedef hala "uygun" karakter dizisi başlatma özelliğini kullanırken aynı 360 karaktere ulaşmaktı. Teşekkürler. :-)
JimmiTh

1

Python 2.7 - 214

Sanırım buna bir daha bakacağım. Bunun daha da aşağı çekilebileceğini hissediyorum, ancak Perl bayt sayısını vurmak zor olacak. Matematik burada benim en büyük sınırlamam gibi görünüyor.

Uyarı: Kullandığınız terminal ne olursa olsun çökebilir. Bunu Windows komut isteminde test ettim lissajous.py 2 3. Komut istemine hızlı yazma nedeniyle, karelerin biraz atlamasını bekleyin. Bu, çoğunlukla daha yüksek kullanılarak (hız pahasına) çözülebilir siçinde range(s)ve t=2*pi*i.

Ben kullanmıyorum \rya da \bbilerek burada kullanıyorum çünkü Windows üzerinde çalıştırıyorum ve ekstra karakterlere mal olacak.

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 Çıktı biraz gergin olsa da Ubuntu üzerinde çalışıyor
Digital Trauma

@DigitalTrauma Evet, zıplama, bunun bir çapraz platform çözümü olmasından kaynaklanıyor (yani Windows komut isteminde çalışmak).
grovesNL
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.