Convexity Test
...
@author 9re
/**
* Copyright 9re ( http://wonderfl.net/user/9re )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/dNEV
*/
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Point;
/**
* ...
* @author 9re
*/
[SWF(backgroundColor="#000000", frameRate="37")]
public class DocumentClass extends Sprite
{
public function DocumentClass()
{
var cvt:ConvexTetragon = new ConvexTetragon();
cvt.addPoint(new Point(150, 50));
cvt.addPoint(new Point(300, 70));
cvt.addPoint(new Point(350, 300));
cvt.addPoint(new Point(140, 200));
cvt.draw();
addChild(cvt);
}
}
}
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
// libs
import gs.easing.*;
import gs.TweenLite;
class Vertex extends Sprite
{
public static var RADIUS:Number = 5;
public static var COLOR:uint = 0xff0000;
public function Vertex($point:Point)
{
x = $point.x;
y = $point.y;
graphics.beginFill(COLOR);
graphics.drawCircle(0, 0, RADIUS);
graphics.endFill();
}
public function get coordinate():Point {
return new Point(x, y);
}
}
class Convex extends Sprite
{
private var _n:int;
protected var _displayObjects:Array;
public function Convex()
{
_displayObjects = [];
}
public function removeAllPoints():void {
while (_displayObjects.length > 0) {
removeChild(_displayObjects.pop());
}
}
public function getPointAt($index:int):Point {
var v:Vertex = _displayObjects[$index] as Vertex;
return v.coordinate;
}
public function addPoint($point:Point):void {
_n = _displayObjects.push(addChild(new Vertex($point)));
}
public function get convexity():Boolean {
if (_n < 4)
return true;
// _points.length > 3
var i:int, j:int;
var sgn:int;
var first:Point;
var second:Point;
var third:Point;
var cross:Number;
var v:Vertex;
for (i = 0; i < _n; ++i) {
v = _displayObjects[i] as Vertex;
first = v.coordinate;
sgn = 2;
for (j = 1; j < _n - 1; ++j) {
v = _displayObjects[(i + j) % _n];
second = v.coordinate;
v = _displayObjects[(i + j + 1) % _n];
third = v.coordinate;
second = second.subtract(first);
third = third.subtract(first);
cross = second.x * third.y - second.y * third.x;
if (cross == 0)
return false;
if (sgn == 2)
sgn = sign(cross);
else if (sgn != sign(cross))
return false;
}
}
return true;
}
private function sign(t:Number):int {
return (t < 0) ? -1 : 1;
}
}
class ConvexTetragon extends Convex
{
public static const VERTEX_MOVED:String = "vertex moved";
public static var FILL_COLOR:uint = 0xffffff;
private var _prevX:Number;
private var _prevY:Number;
private var _v:Vertex;
public function ConvexTetragon()
{
addEventListener(Event.ADDED_TO_STAGE, stageHandler, false, 0, true);
}
private function stageHandler(e:Event):void
{
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
override public function addPoint($point:Point):void
{
super.addPoint($point);
var v:Vertex = _displayObjects[_displayObjects.length - 1];
v.buttonMode = true;
v.tabEnabled = false;
v.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
}
private function mouseDownHandler(e:MouseEvent):void
{
_v = e.target as Vertex;
_prevX = _v.x;
_prevY = _v.y;
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
_v.startDrag();
}
private function mouseUpHandler(e:MouseEvent):void
{
if (_v == null)
return;
_v.stopDrag();
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
if (!convexity) {
TweenLite.to(_v, 0.4, { x: _prevX, y:_prevY, ease:Cubic.easeOut, onComplete:removeEnterFrameHandler } );
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
} else {
dispatchEvent(new Event(VERTEX_MOVED));
draw();
}
draw();
_v = null;
}
private function removeEnterFrameHandler():void
{
removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function enterFrameHandler(e:Event):void
{
draw();
}
public function draw():void
{
var v:Vertex;
v = _displayObjects[0] as Vertex;
graphics.clear();
graphics.beginFill(FILL_COLOR);
graphics.moveTo(v.x, v.y);
for (var i:int = 1; i <= 4; ++i) {
v = _displayObjects[i & 3];
graphics.lineTo(v.x, v.y);
}
graphics.endFill();
}
private function mouseMoveHandler(e:MouseEvent):void
{
e.updateAfterEvent();
draw();
}
}