Heart
キュン☆キュン☆
http://mathworld.wolfram.com/HeartSurface.html
/**
* Copyright yuuganisakase ( http://wonderfl.net/user/yuuganisakase )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/x3lQ
*/
//キュン☆キュン☆
//http://mathworld.wolfram.com/HeartSurface.html
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.events.Event;
import flash.filters.BlurFilter;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import org.papervision3d.core.effects.BitmapLayerEffect;
import org.papervision3d.core.effects.utils.BitmapClearMode;
import org.papervision3d.core.geom.Pixels;
import org.papervision3d.core.geom.renderables.Pixel3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.view.BasicView;
import org.papervision3d.view.layer.BitmapEffectLayer;
[SWF(width="465", height="465", backgroundColor="0x000000", frameRate="20")]
public class Heart extends BasicView
{
private const ZERO_POINT:Point = new Point(0, 0);
private const BLUR:BlurFilter = new BlurFilter(4, 4, 1);
private var hm:HeartMath = new HeartMath();
private var counter:Number = -1;
private var pixels:Pixels;
private var _canvas:BitmapData;;
private var rect:Rectangle;
private var _matrix:Matrix;
public function Heart()
{
Wonderfl.capture_delay(15);
super(465/4, 465/4,true, true, "Target");
var layer:BitmapEffectLayer = new BitmapEffectLayer(viewport,465,465,false);// , true, 0, BitmapClearMode.CLEAR_PRE, true);
layer.clearBeforeRender = true;
layer.addEffect(new BitmapLayerEffect(new BlurFilter(4,4,2), true));
viewport.containerSprite.addLayer(layer);
pixels = new Pixels(layer);
scene.addChild(pixels);
pixels.rotationZ = 90;
pixels.z = -470;
pixels.y = -310;
camera.target = pixels;
//http://wonderfl.net/code/bc7f3d9b6c859128e6c0d944c50c0451de0e3067
_canvas =new BitmapData(465 / 4, 465 / 4, false, 0x000000);
var bmp:Bitmap=new Bitmap(_canvas, "never", true);
bmp.scaleX=bmp.scaleY=4;
bmp.smoothing=true;
bmp.blendMode = BlendMode.ADD;
bmp.alpha = 0.7;
viewport.addChild(bmp);
_matrix = new Matrix(0.25, 0, 0, 0.25);
/* for (var i:Number = -span; i < span; i+=0.1)
{
for (var j:Number = -span; j < span; j+=Step)
{
divideCals( -1.1, 1.1, i, j);
}
}
*/
startRendering();
addEventListener(Event.ENTER_FRAME, onFrame);
}
private function divideCals(start:Number, end:Number, ii:Number, jj:Number):void
{
var ind:Array = [0]
var n:Number = 0;
const sc:Number = 250;
const Max:Number = 40;
const divNum:int = 6;
var s:Number = (end - start) / divNum;
const lSize:int = 8;
const color:uint = 0x77ff88aa;
for (var i:int = 0; i < divNum; i++)
{
ind[0] = 0;
n = hm.secant(start + i * s, start + i * s + s, ii, jj, Max, 0.000001, 0.0000001, ind);
if (ind[0] != -1 && n > start && n < end && jj < 0.8 && jj > -0.8) {
var p:Pixel3D = new Pixel3D(color, n * sc, jj * sc * 1.5, ii * sc * 0.4);
pixels.addPixel3D(p);
}
ind[0] = 0;
n = hm.secant2(start + i * s, start + i * s + s, ii, jj, Max, 0.000001, 0.0000001, ind);
if (ind[0] != -1 && n > 0.8 && n < 0.8) {
p = new Pixel3D(color, jj * sc, n * sc * 1.5, ii * sc * 0.4);
pixels.addPixel3D(p);
}
ind[0] = 0;
n = hm.secant3(start + i * s, start + i * s + s, ii, jj, Max, 0.000001, 0.0000001, ind);
if (ind[0] != -1 && n > start && n < end && ii < 0.8 && ii > -0.8 ){
p= new Pixel3D(color, jj * sc, ii * sc * 1.5, n * sc * 0.4);
pixels.addPixel3D(p);
}
}
}
private function onFrame(e:Event):void
{
_canvas.applyFilter(_canvas, _canvas.rect, ZERO_POINT, BLUR);
_canvas.draw(viewport,_matrix);
if(counter < 1){
counter += 0.03;
for (var j:Number = -1; j < 1; j+=0.02)
{
divideCals( -1.1, 1.1, counter, j);
}
}
pixels.rotationX += 0.7;
}
}
}
class HeartMath
{
private function pow(b:Number, p:Number):Number
{
return Math.pow(b, p);
}
private function Fx(xx:Number, yy:Number, zz:Number):Number
{
return pow(2*(pow(xx, 2) + 2*pow(yy, 2) + pow(zz, 2) - 1), 3) -
pow(xx, 2) * pow(zz, 3)/10 -
pow(yy, 2) * pow(zz, 3);
}
//secant method using three factor x,y,z
public function secant(start1:Number, start2:Number,
y0:Number, z0:Number,
max:int,
eps1:Number, eps2:Number,
ind:Array):Number
{
var f:Number, f1:Number, f2:Number, x:Number;
var count:int = 0;
ind[0] = 0;
f1 = Fx(y0,z0,start1);
f2 = Fx( y0,z0,start2);
if (Math.abs(f1) < eps2)
{
x = start1;
}else {
if (Math.abs(f2) < eps2)
{
x = start2;
}else {
while (ind[0] == 0)
{
count += 1;
if (Math.abs(f2 - f1) < eps2)
{
ind[0] = -1;
}else {
x = start2 - f2 * (start2 - start1) / (f2 - f1);
f = Fx(y0, z0,x);
if (Math.abs(f) < eps2 ||
Math.abs(start2 - start1) < eps1 ||
Math.abs(start2 - start1) < eps1 * Math.abs(start2))
{
ind[0] = count;
}else {
if (count < max)
{
if (f1 * f2 < 0)
{
start2 = x;
f2 = f;
}else {
start1 = x;
f1 = f;
}
}else {
ind[0] = -1;
}
}
}
}
}
}
return x;
}
public function secant2(start1:Number, start2:Number,
x0:Number, z0:Number,
max:int,
eps1:Number, eps2:Number,
ind:Array):Number
{
var f:Number, f1:Number, f2:Number, y:Number;
var count:int = 0;
ind[0] = 0;
f1 = Fx(x0,start1,z0);
f2 = Fx(x0,start2,z0);
if (Math.abs(f1) < eps2)
{
y = start1;
}else {
if (Math.abs(f2) < eps2)
{
y = start2;
}else {
while (ind[0] == 0)
{
count += 1;
if (Math.abs(f2 - f1) < eps2)
{
ind[0] = -1;
}else {
y = start2 - f2 * (start2 - start1) / (f2 - f1);
f = Fx(x0,y, z0);
if (Math.abs(f) < eps2 ||
Math.abs(start2 - start1) < eps1 ||
Math.abs(start2 - start1) < eps1 * Math.abs(start2))
{
ind[0] = count;
}else {
if (count < max)
{
if (f1 * f2 < 0)
{
start2 = y;
f2 = f;
}else {
start1 = y;
f1 = f;
}
}else {
ind[0] = -1;
}
}
}
}
}
}
return y;
}
public function secant3(start1:Number, start2:Number,
y0:Number, z0:Number,
max:int,
eps1:Number, eps2:Number,
ind:Array):Number
{
var f:Number, f1:Number, f2:Number, x:Number;
var count:int = 0;
ind[0] = 0;
f1 = Fx(start1,y0,z0);
f2 = Fx(start2,y0,z0);
if (Math.abs(f1) < eps2)
{
x = start1;
}else {
if (Math.abs(f2) < eps2)
{
x = start2;
}else {
while (ind[0] == 0)
{
count += 1;
if (Math.abs(f2 - f1) < eps2)
{
ind[0] = -1;
}else {
x = start2 - f2 * (start2 - start1) / (f2 - f1);
f = Fx(x,y0, z0);
if (Math.abs(f) < eps2 ||
Math.abs(start2 - start1) < eps1 ||
Math.abs(start2 - start1) < eps1 * Math.abs(start2))
{
ind[0] = count;
}else {
if (count < max)
{
if (f1 * f2 < 0)
{
start2 = x;
f2 = f;
}else {
start1 = x;
f1 = f;
}
}else {
ind[0] = -1;
}
}
}
}
}
}
return x;
}
}