Frocessingでリボン
/**
* Copyright uwi ( http://wonderfl.net/user/uwi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/oF30
*/
package {
import frocessing.display.*;
import flash.geom.*;
import flash.text.TextField;
import net.hires.debug.*;
[SWF(frameRate=60)]
public class Ribbon extends F5MovieClip3D {
private var _vertices : Vector.<Number>;
private const L : uint = 200; // リボンの長さ
private const T : Number = 10; // リボンの太さ
private const V : Number = 10.0; // リボンの速度
private const OMEGA : Number = 0.3; // リボンの最大旋回量
private const SKIP : uint = 2;
// リボンの向き
private var _front : Vector3D;
private var _up : Vector3D;
private var _x : Vector3D; // リボンの座標
private var _xtarg : Vector3D; // リボンターゲットの座標
private var _tf : TextField;
public function setup() : void
{
_tf = new TextField();
// addChild(_tf);
_tf.width = 400;
_tf.height = 200;
addChild(new Stats());
var i : int;
// 頂点
_vertices = new Vector.<Number>();
for(i = 0;i < L;i++){
_vertices.push(T / 2, 0, 100);
_vertices.push(-T / 2, 0, 100);
}
_front = new Vector3D(0, 0, 1);
_up = new Vector3D(0, 1, 0);
_x = new Vector3D(0, 0, 100);
_xtarg = new Vector3D(50, -50, 100);
camera(
0, 0, -200,
0, 0, 1,
0, 1, 0
);
}
public function draw() : void
{
var i : int;
move();
noStroke();
beginShape();
beginFill(0x000000, 1);
curveVertex3d(_vertices[0], _vertices[1], _vertices[2]);
for(i = 2*(_t%SKIP);i < 2 * L;i+=2*SKIP){
curveVertex3d(_vertices[i*3], _vertices[i*3+1], _vertices[i*3+2]);
}
curveVertex3d(_vertices[2*(L-1)*3], _vertices[2*(L-1)*3+1], _vertices[2*(L-1)*3+2]);
curveVertex3d(_vertices[2*(L-1)*3+3], _vertices[2*(L-1)*3+4], _vertices[2*(L-1)*3+5]);
for(i = 2 * L - 2 - 2*(_t%SKIP);i >= 0;i-=2*SKIP){
curveVertex3d(_vertices[i*3+3], _vertices[i*3+4], _vertices[i*3+5]);
}
curveVertex3d(_vertices[3], _vertices[4], _vertices[5]);
// curveVertex3d(_vertices[0], _vertices[1], _vertices[2]);
endFill();
endShape();
}
private var _t : uint = 0;
private function move() : void
{
_t++;
if(_t % 60 == 0 || Vector3D.distance(_xtarg, _x) < 10){
// 目標換え
var z : Number = Math.random();
var sq : Number = Math.sqrt(1 - z * z);
var theta : Number = Math.random() * 2 * Math.PI;
_xtarg.x = Math.cos(theta) * sq * 100;
_xtarg.y = Math.sin(theta) * sq * 100;
_xtarg.z = z * 100;
}
// 旋回
var delta : Vector3D = _xtarg.subtract(_x);
delta.normalize();
var cosd : Number = _front.dotProduct(delta);
if(cosd < 0.999){
var N : Vector3D = _front.crossProduct(delta);
N.normalize();
var d : Number = Math.acos(cosd);
var angle : Number = d < OMEGA ? d : OMEGA;
Vector3DUtils.rotateMulti([_front, _up], N, angle);
}
camera(
-200 * Math.sin(_t * 0.01), 0, -200 * Math.cos(_t * 0.01),
Math.sin(_t * 0.01), 0, Math.cos(_t * 0.01),
0, 1, 0
);
// 進行
_x.x += _front.x * V;
_x.y += _front.y * V;
_x.z += _front.z * V;
var i : uint;
for(i = 2;i < 2*L;i+=2){
_vertices[(i-2)*3] = _vertices[i*3];
_vertices[(i-2)*3+1] = _vertices[i*3+1];
_vertices[(i-2)*3+2] = _vertices[i*3+2];
_vertices[(i-2)*3+3] = _vertices[i*3+3];
_vertices[(i-2)*3+4] = _vertices[i*3+4];
_vertices[(i-2)*3+5] = _vertices[i*3+5];
}
var X : Vector3D = _front.crossProduct(_up);
_vertices[(2*L-2)*3] = _x.x - X.x * T/2;
_vertices[(2*L-2)*3+1] = _x.y - X.y * T/2;
_vertices[(2*L-2)*3+2] = _x.z - X.z * T/2;
_vertices[(2*L-2)*3+3] = _x.x + X.x * T/2;
_vertices[(2*L-2)*3+4] = _x.y + X.y * T/2;
_vertices[(2*L-2)*3+5] = _x.z + X.z * T/2;
}
private function tr(...o : Array) : void
{
_tf.appendText(o + "\n");
}
}
}
import flash.geom.*;
class Vector3DUtils
{
public static function rotate(x : Vector3D, axis : Vector3D, angle : Number) : Vector3D
{
var nCos:Number = Math.cos(angle);
var nSin:Number = Math.sin(angle);
var scos:Number = 1 - nCos;
var sxy :Number = axis.x * axis.y * scos;
var syz :Number = axis.y * axis.z * scos;
var sxz :Number = axis.x * axis.z * scos;
var sz :Number = nSin * axis.z;
var sy :Number = nSin * axis.y;
var sx :Number = nSin * axis.x;
var nx : Number = (nCos + axis.x * axis.x * scos) * x.x + (-sz + sxy) * x.y + (sy + sxz) * x.z;
var ny : Number = (sz + sxy) * x.x + (nCos + axis.y * axis.y * scos) * x.y + (-sx + syz) * x.z;
var nz : Number = (-sy + sxz) * x.x + (sx + syz) * x.y + (nCos + axis.z * axis.z * scos) * x.z;
x.x = nx; x.y = ny; x.z = nz;
return x;
}
public static function rotateMulti(xs : Array, axis : Vector3D, angle : Number) : void
{
var nCos:Number = Math.cos(angle);
var nSin:Number = Math.sin(angle);
var scos:Number = 1 - nCos;
var sxy :Number = axis.x * axis.y * scos;
var syz :Number = axis.y * axis.z * scos;
var sxz :Number = axis.x * axis.z * scos;
var sz :Number = nSin * axis.z;
var sy :Number = nSin * axis.y;
var sx :Number = nSin * axis.x;
for each(var x : Vector3D in xs){
var nx : Number = (nCos + axis.x * axis.x * scos) * x.x + (-sz + sxy) * x.y + (sy + sxz) * x.z;
var ny : Number = (sz + sxy) * x.x + (nCos + axis.y * axis.y * scos) * x.y + (-sx + syz) * x.z;
var nz : Number = (-sy + sxz) * x.x + (sx + syz) * x.y + (nCos + axis.z * axis.z * scos) * x.z;
x.x = nx; x.y = ny; x.z = nz;
}
}
}