Merge JigsawX
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
|
||||
package core;
|
||||
|
||||
import js.Lib;
|
||||
import core.Leaf;
|
||||
import js.html.CanvasElement;
|
||||
import js.html.CanvasRenderingContext2D;
|
||||
import js.html.ImageElement;
|
||||
import js.Browser;
|
||||
using core.Leaf;
|
||||
|
||||
|
||||
typedef Point2D =
|
||||
{
|
||||
var x: Int;
|
||||
var y: Int;
|
||||
}
|
||||
typedef Axis =
|
||||
{
|
||||
var beta: Float;
|
||||
var hyp: Float;
|
||||
}
|
||||
|
||||
|
||||
class Leaf
|
||||
{
|
||||
public static var showBoxes: Bool = false;
|
||||
public static var showCrosses: Bool = false;
|
||||
private static var canvas: CanvasElement;
|
||||
private static var surface: CanvasRenderingContext2D;
|
||||
private static var imageTemp: ImageElement;
|
||||
public static var testSurface: CanvasRenderingContext2D;
|
||||
public var parent: Leaf;
|
||||
public var name: String;
|
||||
// source
|
||||
public var image( default, set_image ): ImageElement;
|
||||
// image position
|
||||
public var x: Int;
|
||||
public var y: Int;
|
||||
// image dim
|
||||
public var w ( default, null ): Int;
|
||||
public var h ( default, null ): Int;
|
||||
// rotation point
|
||||
public var rx: Float;
|
||||
public var ry: Float;
|
||||
// angle in radians
|
||||
public var theta( default, set_theta ): Float;
|
||||
|
||||
// store by depth
|
||||
public var leaves: Array<Leaf>;
|
||||
public var leafCentre: Array<Point2D>;
|
||||
public var leafAxis: Array<Axis>;
|
||||
public var left( default, default ): Int;
|
||||
public var top( default, default ): Int;
|
||||
public var wid( default, null ): Int;
|
||||
public var hi( default, null ): Int;
|
||||
public var cx( default, null ): Float;
|
||||
public var cy( default, null ): Float;
|
||||
public var hyp: Float;
|
||||
public var beta: Float;
|
||||
var dx: Float;
|
||||
var dy: Float;
|
||||
public var offset: Point2D;
|
||||
|
||||
public function set_image( image_: ImageElement ): ImageElement
|
||||
{
|
||||
image = image_;
|
||||
w = image.width;
|
||||
h = image.height;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
public function set_theta( theta_: Float ): Float
|
||||
{
|
||||
if( theta == null ) theta = 0;
|
||||
var dTheta = theta - theta_;
|
||||
theta = theta_;
|
||||
if( rx == null ) rx = 0;
|
||||
if( ry == null ) ry = 0;
|
||||
var sine = Math.sin( theta );
|
||||
var cos = Math.cos( theta );
|
||||
|
||||
// new dimensions
|
||||
wid = Std.int( Math.abs( w*cos ) + Math.abs( h*sine ) );
|
||||
hi = Std.int( Math.abs( w*sine ) + Math.abs( h*cos ) );
|
||||
// new centre
|
||||
cx = wid/2;
|
||||
cy = hi/2;
|
||||
|
||||
// calculates offset of pivot
|
||||
offset = pivotOffset();
|
||||
left = Std.int( x + offset.x );
|
||||
top = Std.int( y + offset.y );
|
||||
|
||||
return theta_;
|
||||
|
||||
}
|
||||
|
||||
public function addLeaf( leaf: Leaf, rx_: Int, ry_: Int )
|
||||
{
|
||||
leafCentre.push( { x: rx_, y: ry_ } );
|
||||
leaves.push( leaf );
|
||||
}
|
||||
|
||||
public function rotate( theta_: Float, rx_: Float, ry_: Float )
|
||||
{
|
||||
rx = rx_;
|
||||
ry = ry_;
|
||||
theta = theta_;
|
||||
for( i in 0...leafCentre.length )
|
||||
{
|
||||
if( leafAxis[i] == null )
|
||||
{
|
||||
var dx2 = rx - leafCentre[i].x;
|
||||
var dy2 = ry - leafCentre[i].y;
|
||||
leafAxis.push( { beta: Math.atan2( dy2, dx2 ), hyp: Math.pow( dx2*dx2 + dy2*dy2, 0.5 ) } );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function new( image_: ImageElement, ?x_: Int = 0, ?y_: Int = 0 )
|
||||
{
|
||||
leaves = [];
|
||||
leafAxis = new Array<Axis>();
|
||||
leafCentre = new Array<Point2D>();
|
||||
image = image_;
|
||||
x = x_;
|
||||
y = y_;
|
||||
|
||||
}
|
||||
|
||||
public function pivotOffset(): Point2D
|
||||
{
|
||||
var dx = w/2 - rx;
|
||||
var dy = h/2 - ry;
|
||||
// calculates the angle from the old centre to the pivot point.
|
||||
beta = Math.atan2( dy, dx );
|
||||
// calculates the diagonal distance from the old centre to the pivot point.
|
||||
hyp = Math.pow( dx*dx + dy*dy, 0.5 );
|
||||
var bt = beta + theta;
|
||||
|
||||
return { x: Std.int( rx - cx + hyp*Math.cos( bt ) )
|
||||
, y: Std.int( ry - cy + hyp*Math.sin( bt ) )
|
||||
};
|
||||
}
|
||||
|
||||
public function renderOn( surfaceOut: CanvasRenderingContext2D )
|
||||
{
|
||||
|
||||
if( canvas == null )
|
||||
{
|
||||
// creates a canvas if one does not exist
|
||||
var dom = Browser.document.createElement('Canvas');
|
||||
canvas = cast dom;
|
||||
surface = untyped canvas.getContext('2d');
|
||||
imageTemp = untyped canvas;
|
||||
}
|
||||
|
||||
canvas.width = wid;
|
||||
canvas.height = hi;
|
||||
// position canvas so whole rotation fits.
|
||||
surface.translate( cx, cy );
|
||||
surface.rotate( theta );
|
||||
// draws to the temporary canvas
|
||||
surface.drawImage( image, -w/2, -h/2, w, h );
|
||||
//surfaceOut.clearRect( 0,0,768,1000);
|
||||
surfaceOut.drawImage( imageTemp, left, top, wid, hi );
|
||||
//var rotPoint = { x: Std.int( left + cx - hyp*Math.cos( beta + theta ) ), y: Std.int(top + cy - hyp*Math.sin( beta + theta ) ) };
|
||||
var bt = beta + theta;
|
||||
var rotX = left + cx - hyp*Math.cos( bt );
|
||||
var rotY = top + cy - hyp*Math.sin( bt );
|
||||
// show top cross
|
||||
if( showCrosses ) surfaceOut.quickCross(
|
||||
{ x: Std.int( rotX )
|
||||
, y: Std.int( rotY ) }
|
||||
);
|
||||
// show boxes
|
||||
if( showBoxes ) addBox( surfaceOut, left, top, wid, hi );
|
||||
|
||||
surface.rotate( -theta );
|
||||
surface.translate( -cx, -cy );
|
||||
surface.clearRect( 0, 0, Math.ceil( cx ), Math.ceil( cy ) );
|
||||
|
||||
for( i in 0...leaves.length )
|
||||
{
|
||||
var axis = leafAxis[ i ];
|
||||
var leaf = leaves[ i ];
|
||||
var loff = leaf.offset;
|
||||
var hyp2 = axis.hyp;
|
||||
var b2t = axis.beta + theta;
|
||||
|
||||
// show bottom cross
|
||||
if( showCrosses ) surfaceOut.quickCross(
|
||||
{ x: Std.int( rotX - hyp2*Math.cos( b2t ) )
|
||||
, y: Std.int( rotY - hyp2*Math.sin( b2t ) ) }
|
||||
);
|
||||
|
||||
|
||||
leaf.left = Std.int( rotX - hyp2*Math.cos( b2t ) + loff.x - leaf.rx ) ;
|
||||
leaf.top = Std.int( rotY - hyp2*Math.sin( b2t ) + loff.y - leaf.ry );
|
||||
|
||||
leaves[ i ].renderOn( surfaceOut );
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//public var rotPoint: Point2D;
|
||||
|
||||
public static inline function addBox( surfaceOut: CanvasRenderingContext2D
|
||||
, left: Int
|
||||
, top: Int
|
||||
, wid: Int
|
||||
, hi: Int
|
||||
)
|
||||
{
|
||||
surfaceOut.beginPath();
|
||||
surfaceOut.strokeStyle = '#00000f';
|
||||
surfaceOut.lineWidth = 0.1;
|
||||
surfaceOut.moveTo( left, top );
|
||||
surfaceOut.lineTo( left + wid, top );
|
||||
surfaceOut.lineTo( left + wid, top + hi );
|
||||
surfaceOut.lineTo( left, top + hi );
|
||||
surfaceOut.lineTo( left, top );
|
||||
surfaceOut.stroke();
|
||||
}
|
||||
public static inline function quickCross( surface: CanvasRenderingContext2D, p: Point2D )
|
||||
{
|
||||
surface.beginPath();
|
||||
surface.strokeStyle = '#f000f0';
|
||||
surface.lineWidth = 2;
|
||||
surface.moveTo( p.x - 5, p.y );
|
||||
surface.lineTo( p.x + 5, p.y );
|
||||
surface.moveTo( p.x, p.y - 5 );
|
||||
surface.lineTo( p.x, p.y + 5 );
|
||||
surface.stroke();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user