Buat animasi lingkaran ilusi


84

Tugas Anda adalah untuk menghidupkan ilusi lingkaran ini . Sepertinya titik-titik berputar di dalam lingkaran, tetapi mereka sebenarnya hanya bergerak dalam garis lurus.

masukkan deskripsi gambar di sini

Criterias

  • Hasilnya harus dianimasikan. Cara Anda melakukan animasi tidak relevan, dapat menghasilkan .gif, dapat menggambar ke jendela, beberapa layar perangkat atau apa pun.
  • Ini adalah kontes popularitas, jadi Anda mungkin ingin menambahkan beberapa fitur tambahan ke program Anda untuk mendapatkan lebih banyak upvotes, misalnya memvariasikan jumlah poin.
  • Pemenangnya adalah jawaban sah yang paling banyak diperbarui 7 hari setelah pengiriman terakhir yang valid.
  • Jawaban yang benar-benar akan menerapkan titik bergerak pada garis lurus dan bukan sebaliknya lebih disambut

"Pemenang paling valid setelah 7 hari". Jadi jika seseorang memposting sesuatu setiap 6 hari sampai bintang mati, kita tidak punya pemenang?
Kevin L

3
@KevinL yang tidak mungkin terjadi dan saya tidak berpikir bahwa 15 tenaga ekstra itu penting dibandingkan dengan semua upvotes yang Anda dapatkan dari pertanyaan ini yang terbentur ke atas setiap 6 hari.
Martin Ender

1
Terkadang saya bertanya-tanya apakah beberapa orang melakukan ini hanya untuk menyelesaikan pekerjaan ...
Daniel Pendergast

3
"Sepertinya titik-titik berputar di dalam lingkaran, tetapi mereka sebenarnya hanya bergerak dalam garis lurus.", Atau, mungkin mereka benar-benar berputar di dalam lingkaran dan tampak bergerak dalam garis lurus ...
coredump

1
Tidak bisa .. mengeluarkan animasi ini .. keluar dari pikiran saya .. terutama versi 3 poin!
Thomas

Jawaban:


126

Python 3.4

Menggunakan modul kura-kura. Kura-kura adalah warna yang berbeda dan mereka selalu menghadap ke arah yang sama, sehingga mereka dapat dengan mudah terlihat bergerak sepanjang garis lurus dengan hanya berfokus pada salah satu dari mereka. Meskipun demikian, ilusi lingkaran masih kuat.

11 kura-kura

Ilusi itu tampaknya masih cukup kuat bahkan hanya dengan 3 atau 4 kura-kura:

3 kura-kura4 kura-kura

Framerate sangat berkurang untuk semua contoh GIF ini, tetapi sepertinya tidak mengurangi ilusi. Menjalankan kode secara lokal memberikan animasi yang lebih halus.

import turtle
import time
from math import sin, pi
from random import random


def circle_dance(population=11, resolution=480, loops=1, flip=0, lines=0):
    population = int(population)
    resolution = int(resolution)
    radius = 250
    screen = turtle.Screen()
    screen.tracer(0)
    if lines:
        arrange_lines(population, radius)
    turtles = [turtle.Turtle() for i in range(population)]
    for i in range(population):
        dancer = turtles[i]
        make_dancer(dancer, i, population)
    animate(turtles, resolution, screen, loops, flip, radius)


def arrange_lines(population, radius):
    artist = turtle.Turtle()
    for n in range(population):
        artist.penup()
        artist.setposition(0, 0)
        artist.setheading(n / population * 180)
        artist.forward(-radius)
        artist.pendown()
        artist.forward(radius * 2)
    artist.hideturtle()


def make_dancer(dancer, i, population):
    dancer.setheading(i / population * 180)
    dancer.color(random_turtle_colour())
    dancer.penup()
    dancer.shape('turtle')
    dancer.turtlesize(2)


def random_turtle_colour():
    return random() * 0.9, 0.5 + random() * 0.5, random() * 0.7


def animate(turtles, resolution, screen, loops, flip, radius):
    delay = 4 / resolution      # 4 seconds per repetition
    while True:
        for step in range(resolution):
            timer = time.perf_counter()
            phase = step / resolution * 2 * pi
            draw_dancers(turtles, phase, screen, loops, flip, radius)
            elapsed = time.perf_counter() - timer
            adjusted_delay = max(0, delay - elapsed)
            time.sleep(adjusted_delay)


def draw_dancers(turtles, phase, screen, loops, flip, radius):
    population = len(turtles)
    for i in range(population):
        individual_phase = (phase + i / population * loops * pi) % (2*pi)
        dancer = turtles[i]
        if flip:
            if pi / 2 < individual_phase <= 3 * pi / 2:
                dancer.settiltangle(180)
            else:
                dancer.settiltangle(0)
        distance = radius * sin(individual_phase)
        dancer.setposition(0, 0)
        dancer.forward(distance)
    screen.update()


if __name__ == '__main__':
    import sys
    circle_dance(*(float(n) for n in sys.argv[1:]))

Untuk kontras, berikut adalah beberapa yang benar-benar berputar:

23 kura-kura lingkaran23 kura-kura trefoil

... atau mereka?

Kode dapat dijalankan dengan 5 argumen opsional: populasi, resolusi, loop, flip dan garis.

  • population adalah jumlah kura-kura
  • resolution adalah resolusi waktu (jumlah bingkai animasi per pengulangan)
  • loopsmenentukan berapa kali kura-kura kembali pada diri mereka sendiri. Default 1 memberikan lingkaran standar, angka ganjil lainnya memberikan jumlah loop dalam string kura-kura, sementara angka genap memberikan string kura-kura yang terputus di ujungnya, tetapi masih dengan ilusi gerakan melengkung.
  • flipjika bukan nol menyebabkan kura-kura membalik arah untuk perjalanan kembali mereka (seperti yang disarankan oleh aslum sehingga mereka tidak pernah bergerak mundur). Sebagai default mereka menjaga arah tetap untuk menghindari gangguan visual di titik akhir.
  • lines jika bukan nol menampilkan garis di mana kura-kura bergerak, untuk konsistensi dengan contoh gambar dalam pertanyaan.

Contoh dengan flipset, dengan dan tanpa lines. Saya telah meninggalkan contoh utama saya di atas tanpa flip karena saya lebih suka untuk tidak memiliki lompatan sporadis, tetapi tepi lingkaran memang terlihat lebih halus dengan semua kura-kura sejajar, jadi ada pilihan bagi orang untuk memilih gaya mana pun yang mereka sukai ketika menjalankan Kode.

11 kura-kura dengan flip dan garis11 kura-kura dengan flip

Mungkin tidak segera jelas bagaimana gambar di atas dihasilkan dari kode yang sama. Khususnya gambar lebih lanjut yang memiliki loop luar yang lambat dan loop dalam yang cepat (yang terlihat seperti cardioid yang secara tidak sengaja dijatuhkan seseorang). Saya telah menyembunyikan penjelasan di bawah ini jika ada yang ingin menunda mencari tahu saat bereksperimen / berpikir.

Animasi dengan lingkaran dalam dan luar dengan ukuran yang berbeda dibuat dengan mengatur jumlah loop menjadi 15 dan meninggalkan jumlah kura-kura di 23 (terlalu rendah untuk mewakili 15 loop). Menggunakan banyak kura-kura akan menghasilkan 15 loop yang jelas. Menggunakan terlalu sedikit kura-kura menghasilkan aliasing (untuk alasan yang sama seperti dalam pemrosesan gambar dan rendering). Mencoba untuk merepresentasikan frekuensi yang terlalu tinggi menghasilkan frekuensi yang lebih rendah ditampilkan, dengan distorsi.

Mencoba angka yang berbeda, saya menemukan beberapa distorsi ini lebih menarik daripada yang asli lebih simetris, jadi saya ingin memasukkan satu di sini ...


18
Saya suka kura-kura.
FreeAsInBeer

18
Saya memberi +1 untuk kura-kura
MrEngineer13

@ProgramFOX terima kasih untuk penyorotan sintaks! Saya mencari melalui bantuan dan meta dan meyakinkan diri sendiri bahwa kami tidak memiliki sintaks menyoroti kode golf - saya jauh lebih bahagia dengan ini sekarang.
trichoplax

1
@aslum itu akan menjadi perubahan langsung untuk dilakukan, tetapi saya ingin orientasi mereka beku benar-benar menekankan bahwa mereka tidak menyimpang dari jalur lurus mereka. Mungkin saya harus menambahkannya ke kode sebagai opsi sehingga orang dapat memilih pendekatan yang mereka sukai.
trichoplax

4
+1 - Akan luar biasa melihat marching band melakukan beberapa yang lebih lucu ini!
mkoistinen

96

C

Hasil:

masukkan deskripsi gambar di sini

#include <stdio.h>
#include <Windows.h>
#include <Math.h>

int round (double r) { return (r > 0.0) ? (r + 0.5) : (r - 0.5); }
void print (int x, int y, char c) {
    COORD p = { x, y };
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), p);
    printf("%c", c);
}

int main ()
{
    float pi = 3.14159265358979323846;
    float circle = pi * 2;
    int len = 12;
    int hlen = len / 2;
    int cx = 13;
    int cy = 8;
    float w = 11.0;
    float h =  8.0;
    float step = 0.0;

    while (1)
    {
        system("cls"); // xD

        for (int i = 0; i < len; i++)
        {
            float a = (i / (float)len) * circle;
            int x = cx + round(cos(a) * w);
            int y = cy + round(sin(a) * h);
            print(x, y, 'O');

            if (i < hlen) continue;

            step -= 0.05;
            float range = cos(a + step);
            x = cx + round(cos(a) * (w - 1) * range);
            y = cy + round(sin(a) * (h - 1) * range);
            print(x, y, 'O');
        }

        Sleep(100);
    }

    return 0;
}

3
Dalam beberapa frame agak tidak aktif. Tapi selamat untuk melakukannya di ASCII!
justhalf

10
+1 untuk ASCII dansystem("cls"); // xD
Christoph Böhmwalder

1
Ini indah.
trichoplax

1
Yang ini bekerja di linux. (walaupun cukup menyedihkan)
user824294

Komentar pembenci yang wajib: "Ini bukan C! Standar tidak mendefinisikan Sleep, COORD atau SetConsoleCursorPosition!"
user253751

52

SVG (tanpa Javascript)

Tautan JSFiddle di sini

<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 380 380" width="380" height="380" version="1.0">
  <g transform="translate(190 190)">
    <circle cx="0" cy="0" r="190" fill="#000"/>
    <line x1="0" y1="-190" x2="0" y2="190" stroke="#fff" stroke-width="1.5"/>
    <line x1="72.71" y1="175.54" x2="-72.71" y2="-175.54" stroke="#fff" stroke-width="1.5"/>
    <line x1="134.35" y1="134.35" x2="-134.35" y2="-134.35" stroke="#fff" stroke-width="1.5"/>
    <line x1="175.54" y1="72.71" x2="-175.54" y2="-72.71" stroke="#fff" stroke-width="1.5"/>
    <line x1="190" y1="0" x2="-190" y2="0" stroke="#fff" stroke-width="1.5"/>
    <line x1="175.54" y1="-72.71" x2="-175.54" y2="72.71" stroke="#fff" stroke-width="1.5"/>
    <line x1="134.35" y1="-134.35" x2="-134.35" y2="134.35" stroke="#fff" stroke-width="1.5"/>
    <line x1="72.71" y1="-175.54" x2="-72.71" y2="175.54" stroke="#fff" stroke-width="1.5"/>
    <g transform="rotate(0)">
      <animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0" to="360" begin="0" dur="8s" repeatCount="indefinite"/>
      <g transform="translate(0 90)">
        <g transform="rotate(0)">
          <animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0" to="-360" begin="0" dur="4s" repeatCount="indefinite"/>
          <circle cx="0" cy="90" r="10" fill="#fff"/>
          <circle cx="63.64" cy="63.64" r="10" fill="#fff"/>
          <circle cx="90" cy="0" r="10" fill="#fff"/>
          <circle cx="63.64" cy="-63.64" r="10" fill="#fff"/>
          <circle cx="0" cy="-90" r="10" fill="#fff"/>
          <circle cx="-63.64" cy="-63.64" r="10" fill="#fff"/>
          <circle cx="-90" cy="0" r="10" fill="#fff"/>
          <circle cx="-63.64" cy="63.64" r="10" fill="#fff"/>
        </g>
      </g>
    </g>
  </g>
</svg>

Hmmm, saya yakin ini sesuai dengan aturan, tetapi saya, secara pribadi, kecewa bahwa Anda sebenarnya melakukan yang sebaliknya. Alih-alih "Sepertinya titik berputar di dalam lingkaran, tetapi mereka sebenarnya hanya bergerak dalam garis lurus .", Anda mengimplementasikan: "Sepertinya titik bergerak dalam garis lurus, tetapi mereka sebenarnya hanya berputar di dalam lingkaran . "
mkoistinen

Jawaban paling halus!
Derek 朕 會 功夫

14
@mkoistinen Saya mengerti maksud Anda, tetapi poinnya benar-benar bergerak dalam garis lurus. Kebetulan lebih mudah untuk menghitung posisi mereka dengan dua rotasi :-)
squeamish ossifrage

Apakah Anda melakukan semuanya 'dengan tangan' atau apakah Anda menggunakan editor (bukan teks)?
flawr

5
@ flawr Saya baru saja menggunakan editor teks biasa dan kalkulator di ponsel saya untuk menghitung angka :-)
sssssssssrr squeamish

47

http://jsfiddle.net/z6vhD/13/

intervaltimemengubah FPS (FPS = 1000 / intervaltime).
ballsmengubah bola #.
maxstepmenyesuaikan langkah # dalam satu siklus, semakin besar 'halus' itu. 64 harus cukup besar di tempat yang terlihat halus.

Dimodelkan sebagai lingkaran yang bergerak, bukannya menggerakkan bola di sepanjang garis, tetapi efek visual (seharusnya?) Sama. Beberapa kode cukup bertele-tele, tetapi ini bukan kode golf, jadi ...

var intervalTime = 40;
var balls = 8;
var maxstep = 64;

var canvas = $('#c').get(0); // 100% necessary jquery
var ctx = canvas.getContext('2d');
var step = 0;

animateWorld = function() {
    createBase();
    step = step % maxstep;
    var centerX = canvas.width/2 + 115 * Math.cos(step * 2 / maxstep * Math.PI);
    var centerY = canvas.height/2 + 115 * Math.sin(step * 2 / maxstep * Math.PI);

    for (var i=0; i<balls; i++) {
        drawCircle(ctx, (centerX + 115 * Math.cos((i * 2 / balls - step * 2 / maxstep) * Math.PI)), (centerY + 115 * Math.sin((i * 2 / balls - step * 2 / maxstep) * Math.PI)), 10, '#FFFFFF');     
    }

    step++;
}

function createBase() {
    drawCircle(ctx, canvas.width/2, canvas.height/2, 240, '#000000');
    for(var i=0; i<balls*2; i++) {
        drawLine(ctx, canvas.width/2, canvas.height/2, canvas.width/2 + 240 * Math.cos(i / balls * Math.PI), canvas.height/2 + 240 * Math.sin(i / balls * Math.PI), '#FFFFFF');
    }
}

function drawLine(context, x1, y1, x2, y2, c) {
    context.beginPath();
    context.moveTo(x1,y1);
    context.lineTo(x2,y2);
    context.lineWidth = 3;
    context.strokeStyle = c;
    context.stroke();
}

function drawCircle(context, x, y, r, c) {
    context.beginPath();
    context.arc(x, y, r, 0, 2*Math.PI);
    context.fillStyle = c;
    context.fill();
}

function drawRect(context, x, y, w, h, c) {
    context.fillStyle = c;
    context.fillRect(x, y, w, h);
}

$(document).ready(function() {
    intervalID = window.setInterval(animateWorld, intervalTime);
});

2
Sangat mulus! Sangat bagus.
nneonneo

5
Jangan gunakan setInterval untuk animasi, ambil requestAnimationFramesaja . JSFiddle dimodifikasi menggunakan requestAnimationFrame.
klingt.net

1
Dengan hanya beberapa parameter tweak Anda mendapatkan hal yang sangat berbeda .
FreeAsInBeer

@ KevinL Yap, perhatikan itu juga. Diperbarui.
FreeAsInBeer

1
@FreeAsInBeer Oh, ketika Anda mengatakan hal yang sangat berbeda, saya pikir Anda bermaksud seperti yang ada di jsfiddle.net/z6vhD/100
Kevin L

41

Animasi CSS

Solusi yang hanya menggunakan animasi css (lihat animasi di JSFiddle - perhatikan bahwa saya menambahkan awalan khusus peramban di biola agar dapat bekerja di sebagian besar versi terbaru).

<body>
    <div id="w1"></div>
    <div id="w2"></div>
    <div id="w3"></div>
    <div id="w4"></div>
    <div id="w5"></div>
    <div id="w6"></div>
    <div id="w7"></div>
    <div id="w8"></div>
</body>


div {
    position: absolute;
    width: 20px;
    height: 20px;
    border-radius: 20px;
    background: red;
    animation-duration: 4s;
    animation-iteration-count: infinite;
    animation-direction: alternate;
    animation-timing-function: ease-in-out;
}

#w1 { animation-name: s1; animation-delay: 0.0s }
#w2 { animation-name: s2; animation-delay: 0.5s }
#w3 { animation-name: s3; animation-delay: 1.0s }
#w4 { animation-name: s4; animation-delay: 1.5s }
#w5 { animation-name: s5; animation-delay: 2.0s }
#w6 { animation-name: s6; animation-delay: 2.5s }
#w7 { animation-name: s7; animation-delay: 3.0s }
#w8 { animation-name: s8; animation-delay: 3.5s }

@keyframes s1 { from {top: 100px; left:   0px;} to {top: 100px; left: 200px;} } 
@keyframes s2 { from {top:  62px; left:   8px;} to {top: 138px; left: 192px;} } 
@keyframes s3 { from {top:  29px; left:  29px;} to {top: 171px; left: 171px;} } 
@keyframes s4 { from {top:   8px; left:  62px;} to {top: 192px; left: 138px;} } 
@keyframes s5 { from {top:   0px; left: 100px;} to {top: 200px; left: 100px;} } 
@keyframes s6 { from {top:   8px; left: 138px;} to {top: 192px; left:  62px;} } 
@keyframes s7 { from {top:  29px; left: 171px;} to {top: 171px; left:  29px;} } 
@keyframes s8 { from {top:  62px; left: 192px;} to {top: 138px; left:   8px;} } 

3
Fiddle tidak bekerja untuk saya di Chrome terbaru = /
mkoistinen

1
@mkoistinen - Anda harus menambahkan awalan yang berbeda agar dapat berfungsi di browser yang berbeda. ( -webkit-untuk berbasis Webkit dan -moz-untuk berbasis Mozilla) Berikut adalah biola yang sama dengan awalan yang diperbarui: jsfiddle.net/nBCxz/3
Derek 朕 會 功夫

@mkoistinen Anda benar. Biola baru menambahkan semua awalan peramban yang diperlukan dan bekerja di Chrome terbaru.
Howard

Teks tautan mentah hanya melewatkan tanda kurung penutup - masih dapat digunakan dengan sempurna hanya memberi tahu Anda jika Anda ingin memperbaikinya (saya tidak bisa karena kurang dari 6 karakter untuk diubah).
trichoplax

35

Mathematica

Ini adalah pengajuan yang cukup mudah.

animateCircle[n_] := Animate[Graphics[
   Flatten@{
     Disk[],
     White,
     Map[
      (
        phase = #*2 \[Pi]/n;
        line = {Cos[phase], Sin[phase]};
        {Line[{-line, line}],
         Disk[Sin[t + phase]*line, 0.05]}
        ) &,
      Range[n]
      ]
     },
   PlotRange -> {{-1.1, 1.1}, {-1.1, 1.1}}
   ],
  {t, 0, 2 \[Pi]}
  ]

Jika Anda menelepon, animateCircle[32]Anda akan mendapatkan animasi yang rapi dengan 32 garis dan lingkaran.

masukkan deskripsi gambar di sini

Ini benar-benar mulus di Mathematica, tapi saya harus membatasi jumlah frame untuk GIF sedikit.

Sekarang apa yang terjadi jika Anda meletakkan dua disk di setiap baris? (Yaitu, tambahkan Disk[-Sin[t + phase]*line, 0.05]ke daftar di dalam Map.)

masukkan deskripsi gambar di sini

Anda juga dapat menempatkan mereka 90 ° di luar fase (gunakan Cossebagai ganti -Sin):

masukkan deskripsi gambar di sini


Aku tak tahu apa masalah-masalah kecil yang Anda maksud, mungkin Anda perlu mengubah {t, 0, 2 \[Pi]}ke {t, 0, 2 \[Pi] - 2 \[Pi]/60, 2 \[Pi]/60}sehingga tidak akan ada dua frame identik dan berubah Animateke Table. Maka Anda dapat mengekspor GIF.
desir

@swish ada itu benar-benar membuat garis tambahan aneh yang tidak ada dan cakram di tempat-tempat di mana mereka tidak harus (dan di mana mereka tidak pernah berada dalam hasil aktual Animate). Saya akan mencoba menggunakan Tablelagi.
Martin Ender

@ Berharap Itu berhasil. Saya pikir saya mencoba sesuatu seperti ini kemarin, tetapi ternyata saya tidak melakukannya.
Martin Ender

25

VBScript + VBA + Diagram Pie Excel

Ini akan membuat prosesor Anda sedikit menangis tetapi terlihat cantik dan saya percaya itu bekerja sesuai dengan spesifikasi. Saya menggunakan jawaban @ Fabricio sebagai panduan untuk menerapkan algoritma gerakan lingkaran.

EDIT: Buat beberapa penyesuaian untuk meningkatkan kecepatan render.

Cuplikan layar bagan Pie

Kode:

'Open Excel
Set objX = CreateObject("Excel.Application")
objX.Visible = True
objX.Workbooks.Add

'Populate values
objX.Cells(1, 1).Value = "Lbl"
objX.Cells(1, 2).Value = "Amt"
For fillX = 2 to 17
    objX.Cells(fillX, 1).Value = "V"+Cstr(fillX-1)
    objX.Cells(fillX, 2).Value = "1"
Next

'Create pie
objX.Range("A2:B17").Select
objX.ActiveSheet.Shapes.AddChart.Select
With objX.ActiveChart
    .ChartType = 5 'pieChart
    .SetSourceData  objX.Range("$A$2:$B$17")
    .SeriesCollection(1).Select
End with    

'Format pie
With objX.Selection.Format
    .Fill.ForeColor.RGB = 0 'black
    .Fill.Solid
    .Line.Weight = 2
    .Line.Visible = 1
    .Line.ForeColor.RGB = 16777215 'white
End With

'animation variables
pi = 3.14159265358979323846
circle = pi * 2 : l  = 16.0
hlen = l / 2    : cx = 152.0
cy = 99.0       : w  = 90.0
h  = 90.0       : s  = 0.0
Dim posArry(7,1)

'Animate
While 1 
  For i = 0 to hlen-1
    a = (i / l) * circle
    range = cos(a + s)
    x = cx + cos(a) * w * range
    y = cy + sin(a) * h * range

    If whileInx = 1 Then 
        createOval x, y
    ElseIf whileInx = 2 Then 
        objX.ActiveChart.Legend.Select
    ElseIf whileInx > 2 Then
        ovalName = "Oval "+ Cstr(i+1)
        dx = x - posArry(i,0)
        dy = y - posArry(i,1)
        moveOval ovalName, dx, dy
    End if

    posArry(i,0) = x
    posArry(i,1) = y
  Next

  s=s-0.05
  wscript.Sleep 1000/60 '60fps
  whileInx = 1 + whileInx
Wend

'create circles
sub createOval(posX, posY)
    objX.ActiveChart.Shapes.AddShape(9, posX, posY, 10, 10).Select '9=oval
    objX.Selection.ShapeRange.Line.Visible = 0
    with objX.Selection.ShapeRange.Fill
       .Visible = 1
       .ForeColor.RGB = 16777215 'white
       .solid
    end with
end sub

'move circles
sub moveOval(ovalName, dx, dy)
    with objX.ActiveChart.Shapes(ovalName)      
        .IncrementLeft dx
        .IncrementTop  dy
    end with
end sub

Itu macet bagi saya di baris 81, kesalahan 80070057, "elemen dengan nama yang diberikan tidak ada" atau sesuatu seperti ini (diterjemahkan kembali dari Hongaria, itu sebabnya saya tidak tahu pesan kesalahan yang tepat).
marczellm

Szervusz, @marczellm. Saya dapat mereproduksi kesalahan itu ketika saya mengklik di luar bagan saat sedang "menghidupkan". Anda harus membiarkannya fokus atau program akan mengalami kesalahan. Jika tidak, ini mungkin karena ketidakcocokan dengan Office. Saya di Office 2010 di Win7.
comfortablydrei

Office 2007, Win7. Sepertinya dalam kasus saya bagan tidak mendapatkan fokus sama sekali.
marczellm

21

Excel, 161 byte

Unggul

=2*PI()*(NOW()*24*60*60/A2-FLOOR(NOW()*24*60*60/A2,1))
=ROUND(7*SIN(A1),0)
=ROUND(5*SIN(A1+1*PI()/4),0)
=ROUND(7*SIN(A1+2*PI()/4),0)
=ROUND(5*SIN(A1+3*PI()/4),0)

A2 (titik) menentukan waktu (detik) untuk 'revolusi' penuh.

Setiap sel dalam garis adalah persyaratan dasar yang berkaitan dengan nilai garis yang sesuai. Misalnya, K2 adalah:

 =1*(A5=7)

Dan sel tengah (K9) adalah:

=1*OR(A5=0,A6=0,A7=0,A8=0)

Paksa animasi dengan menahan 'hapus' pada sel acak untuk terus memicu penyegaran.

Saya tahu ini adalah topik lama, tetapi kegiatan baru-baru ini membawanya ke atas dan sepertinya menarik karena beberapa alasan. Pendengar pcg lama, penelepon pertama kali. Bersikaplah lembut.


Wow, luar biasa Anda bisa melakukannya dengan Excel: D
Beta Decay

15

Hanya untuk bersenang-senang dengan PSTricks.

masukkan deskripsi gambar di sini

\documentclass[preview,border=12pt,multi]{standalone}
\usepackage{pstricks}

\psset{unit=.3}

% static point
% #1 : half of the number of points
% #2 : ith point
\def\x[#1,#2]{(3*cos(Pi/#1*#2))}
\def\y[#1,#2]{(3*sin(Pi/#1*#2))}

% oscillated point
% #1 : half of the number of points
% #2 : ith point
% #3 : time parameter
\def\X[#1,#2]#3{(\x[#1,#2]*cos(#3+Pi/#1*#2))}
\def\Y[#1,#2]#3{(\y[#1,#2]*cos(#3+Pi/#1*#2))}

% single frame
% #1 : half of the number of points
% #2 : time parameter
\def\Frame#1#2{%
\begin{pspicture}(-3,-3)(3,3)
    \pstVerb{/I2P {AlgParser cvx exec} bind def}%
    \pscircle*{\dimexpr3\psunit+2pt\relax}
    \foreach \i in {1,...,#1}{\psline[linecolor=yellow](!\x[#1,\i] I2P \y[#1,\i] I2P)(!\x[#1,\i] I2P neg \y[#1,\i] I2P neg)}
    \foreach \i in {1,...,#1}{\pscircle*[linecolor=white](!\X[#1,\i]{#2} I2P \Y[#1,\i]{#2} I2P){2pt}}   
\end{pspicture}}

\begin{document}
\foreach \t in {0,...,24}
{   
    \preview
    \Frame{1}{2*Pi*\t/25} \quad \Frame{2}{2*Pi*\t/25} \quad \Frame{3}{2*Pi*\t/25} \quad \Frame{5}{2*Pi*\t/25} \quad \Frame{10}{2*Pi*\t/25}
    \endpreview
}
\end{document}

11

Fortran

Setiap frame dibuat sebagai file gif individual menggunakan modul Fortran gif di: http://fortranwiki.org/fortran/show/writegif
Lalu saya sedikit curang dengan menggunakan ImageMagick untuk menggabungkan masing-masing gif menjadi satu gif animasi.

Fortran

UPDATE: Set new = .true. untuk mendapatkan yang berikut ini:

masukkan deskripsi gambar di sini

program circle_illusion

use, intrinsic :: iso_fortran_env, only: wp=>real64
use gif_util  !gif writing module from http://fortranwiki.org/fortran/show/writegif

implicit none

logical,parameter :: new = .false.

integer,parameter  :: n        = 500  !550  !size of image (square)     
real(wp),parameter :: rcircle  = n/2  !250  !radius of the big circle
integer,parameter  :: time_sep = 5    !deg

real(wp),parameter :: deg2rad = acos(-1.0_wp)/180.0_wp
integer,dimension(0:n,0:n):: pixel     ! pixel values
integer,dimension(3,0:3)  :: colormap  ! RGB 0:255 for colors 0:ncol    
real(wp),dimension(2)     :: xy
integer,dimension(2)      :: ixy
real(wp)                  :: r,t
integer                   :: i,j,k,row,col,m,n_cases,ang_sep
character(len=10)         :: istr

integer,parameter  :: black = 0
integer,parameter  :: white = 1
integer,parameter  :: red   = 2
integer,parameter  :: gray  = 3    
colormap(:,0) = [0,0,0]          !black
colormap(:,1) = [255,255,255]    !white
colormap(:,2) = [255,0,0]        !red
colormap(:,3) = [200,200,200]    !gray

if (new) then
    ang_sep = 5
    n_cases = 3
else
    ang_sep = 20
    n_cases = 0
end if

do k=0,355,time_sep

    !clear entire image:
    pixel = white      

    if (new) call draw_circle(n/2,n/2,black,n/2)  

    !draw polar grid:    
    do j=0,180-ang_sep,ang_sep
        do i=-n/2, n/2
            call spherical_to_cartesian(dble(i),dble(j)*deg2rad,xy)
            call convert(xy,row,col)
            if (new) then
                pixel(row,col) = gray
            else
                pixel(row,col) = black  
            end if  
        end do
    end do

    !draw dots:
    do m=0,n_cases
        do j=0,360-ang_sep,ang_sep
            r = sin(m*90.0_wp*deg2rad + (k + j)*deg2rad)*rcircle                
            t = dble(j)*deg2rad    
            call spherical_to_cartesian(r,t,xy)
            call convert(xy,row,col)
            if (new) then
                !call draw_circle(row,col,black,10)  !v2
                !call draw_circle(row,col,m,5)       !v2
                call draw_circle(row,col,white,10)   !v3
            else
                call draw_square(row,col,red)        !v1
            end if
        end do
    end do

    !write the gif file for this frame:        
    write(istr,'(I5.3)') k
    call writegif('gifs/test'//trim(adjustl(istr))//'.gif',pixel,colormap)

end do

!use imagemagick to make animated gif from all the frames:
! from: http://thanosk.net/content/create-animated-gif-linux
if (new) then
    call system('convert -delay 5 gifs/test*.gif -loop 0 animated.gif')
else
    call system('convert -delay 10 gifs/test*.gif -loop 0 animated.gif')
end if

!delete individual files:
call system('rm gifs/test*.gif')

contains

    subroutine draw_square(r,c,icolor)

    implicit none
    integer,intent(in) :: r,c  !row,col of center
    integer,intent(in) :: icolor

    integer,parameter :: d = 10 !square size

    pixel(max(0,r-d):min(n,r+d),max(0,c-d):min(n,c+d)) = icolor

    end subroutine draw_square

    subroutine draw_circle(r,c,icolor,d)

    implicit none
    integer,intent(in) :: r,c  !row,col of center
    integer,intent(in) :: icolor
    integer,intent(in) :: d  !diameter

    integer :: i,j

    do i=max(0,r-d),min(n,r+d)
        do j=max(0,c-d),min(n,c+d)
            if (sqrt(dble(i-r)**2 + dble(j-c)**2)<=d) &
                pixel(i,j) = icolor
        end do
    end do

    end subroutine draw_circle

    subroutine convert(xy,row,col)

    implicit none
    real(wp),dimension(2),intent(in) :: xy  !coordinates
    integer,intent(out) :: row,col

    row = int(-xy(2) + n/2.0_wp)
    col = int( xy(1) + n/2.0_wp)

    end subroutine convert

    subroutine spherical_to_cartesian(r,theta,xy)

    implicit none
    real(wp),intent(in) :: r,theta
    real(wp),dimension(2),intent(out) :: xy

    xy(1) = r * cos(theta)
    xy(2) = r * sin(theta)

    end subroutine spherical_to_cartesian

end program circle_illusion

1
Saya suka dampak 'squish' untuk elemen vertikal & horizontal.
Portland Runner

11

Versi C64 wajib .

Salin & tempel di emulator favorit Anda:

Versi C64

1 print chr$(147)
2 poke 53281,0
3 for p=0 to 7
5 x=int(11+(cos(p*0.78)*10)):y=int(12+(sin(p*0.78)*10))
6 poke 1024+x+(y*40),15
9 next p
10 for sp=2040 to 2047:poke sp,13:next sp
20 for i=0 to 62:read a:poke 832+i,a:next i
30 for i=0 to 7:poke 53287+i,i+1:next i
40 rem activate sprites
50 poke 53269,255
60 an=0.0
70 rem maincycle
75 teta=0.0:k=an
80 for i=0 to 7
90 px=cos(k)*64
92 s=i:x=px*cos(teta): y=px*sin(teta): x=x+100: y=y+137: gosub 210
94 teta=teta+0.392699
95 k=k+0.392699
96 next i
130 an=an+0.1
140 goto 70
150 end
200 rem setspritepos
210 poke 53248+s*2,int(x): poke 53249+s*2,int(y)
220 return
5000 data 0,254,0
5010 data 3,199,128
5020 data 7,0,64
5030 data 12,126,96
5040 data 25,255,48
5050 data 59,7,152
5060 data 52,1,200
5070 data 116,0,204
5080 data 120,0,100
5090 data 120,0,100
5100 data 120,0,100
5110 data 120,0,36
5120 data 104,0,36
5130 data 100,0,108
5140 data 54,0,72
5150 data 51,0,152
5160 data 25,131,16
5170 data 12,124,96
5180 data 4,0,64
5190 data 3,1,128
5200 data 0,254,0

10

Versi javascript ringkas, mengubah pengaturan default menjadi sesuatu yang berbeda

http://jsfiddle.net/yZ3DP/1/

HTML:

<canvas id="c" width="400" height="400" />

JavaScript:

var v= document.getElementById('c');
var c= v.getContext('2d');
var w= v.width, w2= w/2;
var num= 28, M2= Math.PI*2, da= M2/num;
draw();
var bw= 10;
var time= 0;
function draw()
{
    v.width= w;
    c.beginPath();
    c.fillStyle= 'black';
    circle(w2,w2,w2);
    c.lineWidth= 1.5;
    c.strokeStyle= c.fillStyle= 'white';
    var a= 0;
    for (var i=0; i< num*2; i++){
        c.moveTo(w2,w2);
        c.lineTo(w2+Math.cos(a)*w2, w2+Math.sin(a)*w2);
        a+= da/2;
    }
    c.stroke();
    a= 0;
    for (var i=0; i< num; i++){
        circle(w2+Math.cos(a)*Math.sin(time+i*Math.PI/num)*(w2-bw), 
               w2+Math.sin(a)*Math.sin(time+i*Math.PI/num)*(w2-bw), bw);
        a+= da/2;
    }
    time+=0.03;
   requestAnimationFrame(draw);
}

function circle(x,y,r)
{
    c.beginPath();
    c.arc(x, y, r, 0, M2);
    c.fill();

}

2
Anda membuat ... donat ?? Sebenarnya animasi Anda terlihat bagus dengan titik-titik yang lebih kecil (coba bw=10). Harap edit jawaban Anda untuk menunjukkan kode Anda. Oh, dan saat Anda melakukannya, ada bug yang harus Anda perbaiki: ganti time+i*0.39*0.29dengan time+i*Math.PI/numdalam perhitungan trigonometri sehingga koordinat dihitung dengan benar untuk nilai berapa pun num. (PS JSFiddle Diperbarui di sini . Dan selamat datang di codegolf.stackexchange.com)
squeamish ossifrage

Saya hanya ingin membuat sesuatu yang berbeda (seperti kura-kura). Pemula di sini di codegolf :) Oh, dan terima kasih atas rumusnya: DI baru saja melakukannya dengan tergesa-gesa dan mencoba nilai acak, tidak berhenti semenit pun untuk mendapatkan formula yang benar: P
Diego

1
+1 Perubahan kecil untuk bersenang-senang visual: http://jsfiddle.net/9TQrm/ atau http://jsfiddle.net/Wrqs4/1/
Portland Runner

4

Saya ambil dengan Elm . Saya seorang pemula total yang dengan senang hati akan menerima PR untuk meningkatkan solusi ini ( GitHub ):

masukkan deskripsi gambar di sini

Perhatikan bahwa pengajuan ini adalah benar-benar titik bergerak pada garis lurus:

import Color exposing (..)
import Graphics.Collage exposing (..)
import Graphics.Element exposing (..)
import Time exposing (..)
import Window
import List exposing (..)
import AnimationFrame -- "jwmerrill/elm-animation-frame"
import Debug

-- CONFIG

size = 600
circleSize = 240
dotCount = 12
dotSize = 10
velocity = 0.01

-- MODEL

type alias Dot =
    { x : Float
    , angle : Float
    }

type alias State = List Dot

createDots : State
createDots = map createDot [ 0 .. dotCount - 1 ]

createDot : Int -> Dot
createDot index =
    let angle = toFloat index * pi / dotCount
    in { x = 0
       , angle = angle
       }

-- UPDATE

update : Time -> State -> State
update time dots = map (moveDot time) dots |> Debug.watch "Dots"

moveDot : Time -> Dot -> Dot
moveDot time dot =
  let t = velocity * time / pi
      newX = (-circleSize + dotSize) * cos(t + dot.angle)
  in { dot | x <- newX }

-- VIEW

view : State -> Element
view dots =
   let background = filled black (circle circleSize)
       dotLinePairs = map viewDotWithLine dots
   in collage size size (background :: dotLinePairs)

viewDotWithLine : Dot -> Form
viewDotWithLine dot =
  let dotView = viewDot dot
      lineView = createLineView
  in group [dotView , lineView] |> rotate dot.angle

viewDot : Dot -> Form
viewDot d = alpha 0.8 (filled lightOrange (circle dotSize)) |> move (d.x, 0)

createLineView : Form
createLineView = traced (solid white) (path [ (-size / 2.0, 0) , (size / 2.0, 0) ])

-- SIGNALS

main = Signal.map view (animate createDots)

animate : State -> Signal State
animate dots = Signal.foldp update dots time

time = Signal.foldp (+) 0 AnimationFrame.frame

4
Kursor itu menipu saya dengan baik, dan kursor saya bahkan tidak hitam atau seukuran itu.
cole

2

LSL Kehidupan Kedua

animasi mulai dari gambar alpha kura-kura (klik kanan di bawah untuk menyimpan gambar)
turtle.png
akhir gambar alpha kura-kura (klik kanan di atas untuk menyimpan gambar)

membangun objek:
membuat ukuran silinder root primer <1, ​​1, 0,01> irisan 0,49, 0,51, warna < 0, 0, 0>
buat deskripsi silinder ini "8,1,1,1" tanpa tanda kutip (sangat penting)
buat silinder, beri nama "cyl", warna <0,25, 0,25, 0,25> alpha 0,5
duplikat cyl 48 kali
membuat kotak,
beri nama "sphere", warna <1, 1, 1> transparansi 100 kecuali untuk transparansi teratas 0 letakkan tekstur kura-kura Anda di wajah 0 kotak, kura-kura harus menghadapi + x
duplikat kotak 48 kali
pilih semua kotak dan silinder, pastikan untuk memilih silinder akar yang terakhir,tautan (kontrol L)

letakkan 2 skrip ini di root:

//script named "dialog"
default
{
    state_entry()
    {

    }

    link_message(integer link, integer num, string msg, key id)
    {
        list msgs = llCSV2List(msg);
        key agent = (key)llList2String(msgs, 0);
        string prompt = llList2String(msgs, 1);
        integer chan = (integer)llList2String(msgs, 2);
        msgs = llDeleteSubList(msgs, 0, 2);
        llDialog(agent, prompt, msgs, chan);
    }
}

//script named "radial animation"
float interval = 0.1;
float originalsize = 1.0;
float rate = 5;
integer maxpoints = 48;
integer points = 23; //1 to 48
integer multiplier = 15;
integer lines;
string url = "https://codegolf.stackexchange.com/questions/34887/make-a-circle-illusion-animation/34891";

list cylinders;
list spheres;
float angle;
integer running;
integer chan;
integer lh;

desc(integer on)
{
    if(on)
    {
        string desc = 
            (string)points + "," +
            (string)multiplier + "," +
            (string)running + "," +
            (string)lines
            ;

        llSetLinkPrimitiveParamsFast(1, [PRIM_DESC, desc]);
    }
    else
    {
        list params = llCSV2List(llList2String(llGetLinkPrimitiveParams(1, [PRIM_DESC]), 0));
        points = (integer)llList2String(params, 0);
        multiplier = (integer)llList2String(params, 1);
        running = (integer)llList2String(params, 2);
        lines = (integer)llList2String(params, 3);
    }    
}

init()
{
    llSetLinkPrimitiveParamsFast(LINK_ALL_OTHERS, [PRIM_POS_LOCAL, ZERO_VECTOR, 
        PRIM_COLOR, ALL_SIDES, <1, 1, 1>, 0]);
    integer num = llGetNumberOfPrims();
    integer i;
    for(i = 2; i <= num; i++)
    {
        string name = llGetLinkName(i);

        if(name == "cyl")
            cylinders += [i];
        else if(name == "sphere")
            spheres += [i];
    }  

    vector size = llGetScale();
    float scale = size.x/originalsize;

    float r = size.x/4;
    vector cylindersize = <0.01*scale, 0.01*scale, r*4>;
    float arc = 180.0/points;

    for(i = 0; i < points; i++)
    {
        float angle = i*arc;
        rotation rot = llEuler2Rot(<0, 90, 0>*DEG_TO_RAD)*llEuler2Rot(<0, 0, angle>*DEG_TO_RAD);

        integer cyl = llList2Integer(cylinders, i);
        integer sphere = llList2Integer(spheres, i);

        llSetLinkPrimitiveParamsFast(1, [PRIM_LINK_TARGET, cyl, PRIM_POS_LOCAL, ZERO_VECTOR, PRIM_ROT_LOCAL, rot, PRIM_SIZE, cylindersize, PRIM_COLOR, ALL_SIDES, <0.25, 0.25, 0.25>, 0.5*lines,
        PRIM_LINK_TARGET, sphere, PRIM_COLOR, ALL_SIDES, <0.25 + llFrand(0.75), 0.25 + llFrand(0.75), 0.25 + llFrand(0.75)>, 1
        ]);
    }
}

run()
{
    vector size = llGetScale();
    float scale = size.x/originalsize;

    float r = size.x/2;
    vector spheresize = <0.06, 0.06, 0.02>*scale;
    float arc = 180.0/points;
    list params;
    integer i;
    for(i = 0; i < points; i++)
    {

        float x = r*llCos((angle + i*arc*multiplier)*DEG_TO_RAD);

        vector pos = <x, 0, 0>*llEuler2Rot(<0, 0, i*arc>*DEG_TO_RAD);
        rotation rot = llEuler2Rot(<0, 0, i*arc>*DEG_TO_RAD);
        integer link = llList2Integer(spheres, i);
        params += [PRIM_LINK_TARGET, link, PRIM_POS_LOCAL, pos,  
            PRIM_ROT_LOCAL, rot,
            PRIM_SIZE, spheresize
            //PRIM_COLOR, ALL_SIDES, <1, 1, 1>, 1
            ];
    }   

    llSetLinkPrimitiveParamsFast(1, params);
}

dialog(key id)
{
    string runningstring;
    if(running)
        runningstring = "notrunning";
    else
        runningstring = "running";

    string linesstring;
    if(lines)
        linesstring = "nolines";
    else
        linesstring = "lines";
    string prompt = "\npoints: " + (string)points + "\nmultiplier: " + (string)multiplier;
    string buttons = runningstring + ",points+,points-,reset,multiplier+,multiplier-," + linesstring + ",www";
    llMessageLinked(1, 0, (string)id + "," + prompt + "," + (string)chan + "," + buttons, "");
    //llDialog(id, prompt, llCSV2List(buttons), chan);
}

default
{
    state_entry()
    {
        chan = (integer)("0x" + llGetSubString((string)llGetKey(), -8, -1));
        lh = llListen(chan, "", "", "");

        desc(FALSE);
        init();
        run();
        llSetTimerEvent(interval);
    }

    on_rez(integer param)
    {
        llListenRemove(lh);
        chan = (integer)("0x" + llGetSubString((string)llGetKey(), -8, -1));
        lh = llListen(chan, "", "", "");
    }

    touch_start(integer total_number)
    {
        key id = llDetectedKey(0);
        dialog(id);
    }

    timer()
    {
        if(!running)
            return;

        angle += rate;
        if(angle > 360)
            angle -= 360;
        else if(angle < 0)
            angle += 360;

        run();
    }

    listen(integer channel, string name, key id, string msg)
    {
        if(msg == "points+")
        {
            if(points < maxpoints)
            {
                points++;
                desc(TRUE);
                llResetScript();            
            }
        }
        else if(msg == "points-")
        {
            if(points > 0)
            {
                points--;
                desc(TRUE);
                llResetScript();
            }
        }        
        else if(msg == "multiplier+")
        {
            multiplier++;
            desc(TRUE);
        }
        else if(msg == "multiplier-")
        {
            multiplier--;
            desc(TRUE);
        }
        else if(msg == "running")
        {
            running = TRUE;
            desc(TRUE);
        }
        else if(msg == "notrunning")
        {
            running = FALSE;
            desc(TRUE);
        }
        else if(msg == "lines")
        {
            lines = TRUE;
            desc(TRUE);
            llResetScript();
        }
        else if(msg == "nolines")
        {
            lines = FALSE;
            desc(TRUE);
            llResetScript();
        }
        else if(msg == "reset")
            llResetScript();
        else if(msg == "www")
            llRegionSayTo(id, 0, url);
        dialog(id);
    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.