Involute Curve
Involute
@author Test Dept
/**
* Copyright Test_Dept ( http://wonderfl.net/user/Test_Dept )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/iNLZ
*/
// forked from Test_Dept's GeomTest II
package {
import flash.display.Sprite;
/**
* Involute
* @author Test Dept
*/
[SWF(backgroundColor="#ffffff", width="465", height="465")]
public class Involute extends Sprite {
function Involute() {
addChild(new InvoluteImpl() );
}
}
}
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Point;
class InvoluteImpl extends Sprite {
private var _r : Number;
private var _t : Number;
public function InvoluteImpl() {
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
private function addedToStageHandler(event : Event) : void {
x = stage.stageWidth / 2;
y = stage.stageHeight / 2;
_r = 4;
_t = 6 * Math.PI;
stage.addEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMoveHandler);
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function stage_mouseMoveHandler(event : MouseEvent) : void {
_t = mouseY / _r;
}
private function enterFrameHandler(event : Event) : void {
var g : Graphics = graphics;
g.clear();
// var points : Array = GeoUtil.getInvolutePoints(_r, 0, -_t, 0);
var points : Array = GeoUtil.getInvolutePoints(_r, 0, -_t, _t);
var i : int;
var p : Array;
var c : Point;
var lastP : Array;
lastP = null;
g.lineStyle();
for (i = 0; i < points.length; i++) {
p = points[i];
if (lastP != null) {
g.beginFill(0x0000ff, 0.2);
g.moveTo(lastP[1].x, lastP[1].y);
c = GeoUtil.getCrossPoint(
lastP[2], lastP[1], p[2], p[1]);
g.curveTo(c.x, c.y, p[1].x, p[1].y);
g.lineTo(p[0].x, p[0].y);
c = GeoUtil.getCrossPoint(
new Point(), lastP[0], new Point(), p[0]);
g.curveTo(c.x, c.y, lastP[0].x, lastP[0].y);
g.endFill();
}
lastP = p;
}
lastP = null;
g.lineStyle(4, 0x00ff00, 0.2);
for (i = 0; i < points.length; i++) {
p = points[i];
if (lastP != null) {
c = GeoUtil.getCrossPoint(
lastP[2], lastP[1], p[2], p[1]);
g.curveTo(c.x, c.y, p[1].x, p[1].y);
} else{
g.moveTo(p[1].x, p[1].y);
}
lastP = p;
}
}
}
class GeoUtil {
public static function getInvolutePoints(
r : Number,
minT : Number, maxT : Number,
offsetT : Number = 0, dt : Number = 0.314
) : Array {
var points : Array = new Array();
var div : int = Math.max(1, Math.abs( (maxT - minT) / dt) );
for (var i : int = 0; i <= div; i++) {
var t : Number = (maxT - minT) * i / div + minT;
var mat : Matrix = new Matrix();
mat.rotate(offsetT + t);
points.push([
mat.transformPoint(new Point(r, 0) ),
mat.transformPoint(new Point(r, -r * t) ),
mat.transformPoint(new Point(r, (t == 0)? 1 : 0) )
]);
}
return points;
}
public static function getCrossPoint(
a1 : Point, a2 : Point,
b1 : Point, b2 : Point
) : Point {
var a12 : Point = a2.subtract(a1);
var b12 : Point = b2.subtract(b1);
var mat : Matrix = new Matrix(
-a12.y, a12.x,
-b12.y, b12.x);
mat.invert();
var st : Point = mat.transformPoint(b2.subtract(a2) );
var s : Number = st.x;
return new Point(
a2.x - a12.y * s,
a2.y + a12.x * s);
}
}