/**
* Copyright euakast ( http://wonderfl.net/user/euakast )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/25ix
*/
package
{
import com.bit101.components.*;
import flash.display.*;
import flash.events.*;
public class MathematicsSketch extends Sprite {
private static const NUM_INITIAL_LINES:int = 4;
private var _lines:Array;
private var _connectSprite:Sprite;
private var _container:Sprite;
public function MathematicsSketch() {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
_container = new Sprite();
_container.x = stage.stageWidth * 0.5;
_container.y = stage.stageHeight * 0.5;
addChild(_container);
_connectSprite = new Sprite();
_connectSprite.mouseEnabled = false;
_container.addChild(_connectSprite);
_lines = [];
addLines(NUM_INITIAL_LINES);
drawInterface();
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function addLines(amt:int):void {
var hw:Number = stage.stageWidth * 0.5;
var hh:Number = stage.stageHeight * 0.5;
for (var i:int = 0; i < amt; ++i) {
var a:PointSprite = new PointSprite(_container, new Vec2d(Random.randint(-hw, hw), Random.randint(-hh, hh)));
var b:PointSprite = new PointSprite(_container, new Vec2d(Random.randint(-hw, hw), Random.randint(-hh, hh)));
var line:Line = new Line(a, b);
_lines.push(line);
}
}
private function removeLines(amt:int):void {
while (amt--) {
var line:Line = _lines.splice((_lines.length - 1) - amt, 1)[0];
_container.removeChild(line.a);
_container.removeChild(line.b);
}
}
private function enterFrameHandler(e:Event):void {
drawLine();
drawIntersectionPoint();
}
private function drawLine():void {
_container.graphics.clear();
var l:int = _lines.length;
for (var i:int = 0; i < l; ++i) {
var line:Line = _lines[i];
line.draw(_container.graphics);
}
}
private function drawIntersectionPoint():void {
_connectSprite.graphics.clear();
var l:int = _lines.length;
for (var i:int = 0; i < l; ++i) {
for (var j:int = i + 1; j < l; ++j) {
var crossPoint:Vec2d = intersection(_lines[i].a.pos, _lines[i].b.pos, _lines[j].a.pos, _lines[j].b.pos);
if (crossPoint) {
_connectSprite.graphics.beginFill(0xFF0000);
_connectSprite.graphics.drawCircle(crossPoint.x, crossPoint.y, 6);
_connectSprite.graphics.endFill();
}
}
}
}
private function intersection(a:Vec2d, b:Vec2d, c:Vec2d, d:Vec2d):Vec2d {
return _intersection(a, b.sub(a), c, d.sub(c));
}
private function _intersection(p1:Vec2d, v1:Vec2d, p2:Vec2d, v2:Vec2d):Vec2d {
var cross:Number = v1.cross(v2)
if (cross == 0.0) {
return null;
}
var v:Vec2d = p2.sub(p1);
var t1:Number = v.cross(v2) / cross;
var t2:Number = v.cross(v1) / cross;
if (t1 < 0 || t1 > 1 || t2 < 0 || t2 > 1) {
return null;
}
return p1.add(v1.scale(t1));
}
private function drawInterface():void {
var vBox:VBox = new VBox(this, 10, 10);
var fps:FPSMeter = new FPSMeter(vBox);
var hBox:HBox = new HBox(vBox);
var label:Label = new Label(hBox, 0, 0, "num lines");
var numeric:NumericStepper = new NumericStepper(hBox, 0, 0, function():void {
if (numeric.value > _lines.length) {
addLines(numeric.value - _lines.length);
} else {
removeLines(_lines.length - numeric.value);
}
});
numeric.minimum = 1;
numeric.value = NUM_INITIAL_LINES;
}
}
}
import flash.display.*;
import flash.events.*;
import flash.geom.Point;
class PointSprite extends Sprite {
private var _pos:Vec2d;
private var _radius:Number;
public function PointSprite(parent:DisplayObjectContainer, pos:Vec2d, radius:Number = 6) {
parent.addChildAt(this, 0);
this.pos = pos;
this.radius = radius;
buttonMode = true;
draw();
addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
}
private function mouseDownHandler(e:MouseEvent):void {
startDrag();
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
private function mouseUpHandler(e:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
stopDrag();
}
private function enterFrameHandler(e:Event):void {
_pos.x = x;
_pos.y = y;
}
private function draw():void {
graphics.clear();
graphics.beginFill(0x0);
graphics.drawCircle(0, 0, _radius);
graphics.endFill();
}
public function get pos():Vec2d { return _pos; }
public function set pos(value:Vec2d):void { _pos = value; x = _pos.x; y = _pos.y; }
public function get radius():Number { return _radius; }
public function set radius(value:Number):void { _radius = value; }
}
class Line {
private var _a:PointSprite;
private var _b:PointSprite;
public function Line(a:PointSprite, b:PointSprite) {
_a = a;
_b = b;
}
public function draw(g:Graphics):void {
g.lineStyle(2.0, 0);
g.moveTo(_a.x, _a.y);
g.lineTo(_b.x, _b.y);
}
public function get a():PointSprite { return _a; }
public function get b():PointSprite { return _b; }
public function get v():Vec2d { return _b.pos.sub(_a.pos); }
}
class Vec2d {
public var x:Number, y:Number;
public function Vec2d(ax:Number = 0.0, ay:Number = 0.0) { x = ax; y = ay; }
public function clone():Vec2d { return new Vec2d(x, y); }
public function set(ax:Number, ay:Number):void { x = ax; y = ay; }
public function get length():Number { return Math.sqrt(x * x + y * y); }
public function set length(value:Number):void { var a:Number = angle; x = Math.cos(a) * value; y = Math.sin(a) * value; }
public function get lengthSqrt():Number { return x * x + y * y; }
public function get angle():Number { return Math.atan2(y, x); }
public function normalize():void { var invS:Number = 1 / length; x *= invS; y *= invS; }
public function normalized():Vec2d { var invS:Number = 1 / length; return new Vec2d(x * invS, y * invS); }
public function add(rhs:Vec2d):Vec2d { return new Vec2d(x + rhs.x, y + rhs.y); }
public function sub(rhs:Vec2d):Vec2d { return new Vec2d(x - rhs.x, y - rhs.y); }
public function mul(rhs:Vec2d):Vec2d { return new Vec2d(x * rhs.x, y * rhs.y); }
public function div(rhs:Vec2d):Vec2d { return new Vec2d(x / rhs.x, y / rhs.y); }
public function dot(rhs:Vec2d):Number { return x * rhs.x + y * rhs.y; }
public function cross(rhs:Vec2d):Number { return x * rhs.y - y * rhs.x; }
public function scale(s:Number):Vec2d { return new Vec2d(x * s, y * s); }
public function distance(rhs:Vec2d):Number { var dx:Number = x - rhs.x; var dy:Number = y - rhs.y; return Math.sqrt(dx * dx + dy * dy); }
public function distanceSqrd(rhs:Vec2d):Number { var dx:Number = x - rhs.x; var dy:Number = y - rhs.y; return dx * dx + dy * dy; }
public function rotate(angle:Number):void { var cosa:Number = Math.cos(angle); var sina:Number = Math.sin(angle); var rx:Number = x * cosa - y * sina; y = x * sina + y * cosa; x = rx; }
public function truncate(max:Number):void { this.length = Math.min(max, this.length); }
}
class Random {
public static function random(min:Number = 0, max:Number = NaN):Number {
if (isNaN(max)) { max = min; min = 0; }
return min + Math.random() * (max - min);
}
public static function randint(min:int = 0, max:int = NaN):int {
if (isNaN(max)) { max = min; min = 0; }
return min + Math.floor(Math.random() * (max - min + 1));
}
}