Second Life LSL
start of turtle alpha image (right click below to save image)
end of turtle alpha image (right click above to save image)
building the object:
make a root prim cylinder size <1, 1, 0.01> slice 0.49, 0.51, color <0, 0, 0>
make the description of this cylinder "8,1,1,1" without the quotes (very important)
make a cylinder, name it "cyl", color <0.25, 0.25, 0.25> alpha 0.5
duplicate the cyl 48 times
make a box, name it "sphere", color <1, 1, 1> transparency 100 except for the top transparency 0
put your turtle texture on face 0 of the box, turtle should face +x
duplicate the box 48 times
select all the boxes and the cylinders, make sure to select the root cylinder last, link (control L)
put these 2 scripts in the 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);
}
}
"winner is the most upvoted valid after 7 days". So if someone posts something every 6 days until the stars die, we have no winner? – Kevin L – 2014-07-21T19:52:03.220
3@KevinL that is unlikely to happen and I don't think those 15 extra rep are that important compared to all the upvotes you'd get from this question being bumped to the top every 6 days. – Martin Ender – 2014-07-21T20:09:28.603
@KevinL: If that happens, we will have a winner after the stars die. – Jonathan Pullano – 2014-07-22T17:18:47.193
look closely, and focus on any one of the balls. They are just oscillating along one of their pass axis. – user3459110 – 2014-07-23T04:30:26.677
1Sometimes I wonder if some people do these just to get a job done... – Daniel says Reinstate Monica – 2014-07-23T19:50:53.273
@DantheMan I really enjoyed this question... I think I know what you mean - that need to do something that can be finished quickly for a sense of completion. – trichoplax – 2014-07-23T23:21:45.030
3"It looks like the points rotating inside of the circle, but they are actually just moving in straight lines.", or, maybe they are really rotating inside a circle and appear to move in straight lines ... – coredump – 2014-07-26T21:13:39.883
1Can't.. get this animation.. out of my mind.. especially the 3-point version! – Thomas – 2014-07-28T12:32:07.133