/**
* Copyright bradsedito ( http://wonderfl.net/user/bradsedito )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/bZSc
*/
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.utils.getTimer;
[SWF(backgroundColor="#FFFFFF", frameRate="100")]
public class CassiniTest extends Sprite {
public const sW:Number = new Number(stage.stageWidth);
public const sH:Number = new Number(stage.stageHeight);
public var c1:Cassini = new Cassini;
public var c2:CassiniMod = new CassiniMod;
public function CassiniTest () {
addEventListener (Event.ENTER_FRAME, loop);
this.rotationZ = rotationZ++;
}
public function loop (e:Event):void {
var a:Number = 1 + Math.sin (2e-3 * getTimer ());
var c:Cassini = (c2);
var ranges:Vector.<Range> = c.ranges (a);
graphics.clear ();
graphics.lineStyle (40);
var t:int, X:Number, Y:Number;
for each (var range:Range in ranges) {
// // positive
X = range.x (0);
graphics.moveTo((sW/2)+75*X, (sH/2));
for (t = 1; t < 101; t++) {
X = range.x (t / 100);
Y = c.y (X, a);
graphics.lineTo((sW/2)+75*X, (sH/2) - 75 * Y);
}
// // negative
X = range.x (0);
graphics.moveTo((sW/2)+75*X, (sH/2));
for (t = 1; t < 101; t++) {
X = range.x (t / 100);
Y = c.y (X, a);
// // Changing the (- 75) to a (+ 75) here creates the same effect but with 2 half circles
// // Could be useful maybe?
graphics.lineTo((sW/2)+75*X, (sH/2) + 75 * Y);
}
}
}
}
}
class Range {
public var a:Number;
public var b:Number;
public function Range (from:Number, to:Number) {
a = from; b = to;
}
public function x (t:Number):Number {
return a + (b - a) * t;
}
}
/**
* Cassini oval, a=0..2, b=1.
* @see http://paulbourke.net/geometry/egg/
*/
class Cassini {
public function y (x:Number, a:Number, b:Number = 1):Number {
var a2:Number = a * a, x2:Number = x * x;
var D:Number = Math.max (0, 4 * a2 * x2 + b * b);
var D2:Number = Math.max (0, Math.sqrt (D) - a2 - x2);
return Math.sqrt (D2);
}
/**
* Assumes b=1.
*/
public function ranges (a:Number):Vector.<Range> {
var a2:Number = a * a;
var D:Number = a2 - 1, D2:Number = a2 + 1;
if (D > 0) {
return new <Range> [
new Range ( -Math.sqrt (D2), -Math.sqrt (D)),
new Range ( +Math.sqrt (D), +Math.sqrt (D2))
];
}
return new <Range> [
new Range ( -Math.sqrt (D2), +Math.sqrt (D2))
];
}
}
//Modified Cassini oval.
class CassiniMod extends Cassini {
override public function y (x:Number, a:Number, ignore:Number = 1):Number {
return super.y (x, a, 1 + (a * a + a) / 4);
}
override public function ranges (a:Number):Vector.<Range> {
var a2:Number = a * a;
var D:Number = 3 * a2 - a - 4, D2:Number = 5 * a2 + a + 4;
if (D > 0) {
return new <Range> [
new Range ( -0.5 * Math.sqrt (D2), -0.5 * Math.sqrt (D)),
new Range ( +0.5 * Math.sqrt (D), +0.5 * Math.sqrt (D2))
];
}
return new <Range> [
new Range ( -0.5 * Math.sqrt (D2), +0.5 * Math.sqrt (D2))
];
}
}