Cross product of two 3D vectors returns another vecter that is perpendicular to both the original vecters.
In this example vector A and B are indicated by blue line and green line, respectively, and their product is shown with red line.
A × B = [(a2 * b3 - a3 * b2) (a3 * b1 - a1 * b3) (a1 * b2 - a2 * b1)]
package {
import flash.display.*;
import flash.events.*;
import flash.geom.Point;
import flash.ui.*;
public class Main extends Sprite {
private var points:Array,lines:Array;
private var vp:Pp3dViewPoint;
private var ang1:Number = 0, ang2:Number = 0;
private var va1:Number = Math.PI / 180, va2:Number = Math.PI / 120;
private var canvas:Sprite;
private var colors:Array = [0x0000FF, 0xDDDDDD, 0x00FF00, 0xFF0000];
public function Main() {
addChild(canvas = new Sprite());
canvas.x = stage.stageWidth / 2;
canvas.y = stage.stageHeight / 2;
addEventListener(Event.ENTER_FRAME, h_enterFrame);
vp = new Pp3dViewPoint();
defineShape();
}
protected function h_enterFrame(evt:Event):void {
var g:Graphics = canvas.graphics;
g.clear();
ang1 += va1;
ang2 += va2;
points[1].x = Math.cos(ang1) * 100;
points[1].y = Math.sin(ang1) * 100;
points[2].x = Math.cos(ang2) * 100;
points[2].z = Math.sin(ang2) * 100;
// Cross Product
points[3].x = (points[1].y * points[2].z - points[1].z * points[2].y);
points[3].y = (points[1].z * points[2].x - points[1].x * points[2].z);
points[3].z = (points[1].x * points[2].y - points[1].y * points[2].x);
// Set length to 100
var len = Pp3dObject.distance(new Pp3dPoint(0,0,0), points[3]);
points[3].x = points[3].x / len * 100;
points[3].y = points[3].y / len * 100;
points[3].z = points[3].z / len * 100;
var p:Point;
var op:Point;
var temp:Array = new Array();
var p1:Pp2dPoint, p2:Pp2dPoint;
for (var i:uint = 0; i < points.length; i ++) {
temp.push(vp.projectTo2d(points[i]));
}
g.beginFill(0xDDDDDD,0.2);
g.lineStyle(0,colors[0]);
g.lineTo(temp[1].x, temp[1].y);
g.lineStyle(0,colors[1]);
g.lineTo(temp[2].x, temp[2].y);
g.lineStyle(0,colors[2]);
g.lineTo(0,0);
g.endFill();
g.lineStyle(0,colors[3]);
g.lineTo(temp[3].x, temp[3].y);
}
private function defineShape():void {
points = [ new Pp3dPoint(0,0,0),
new Pp3dPoint(0,0,0),
new Pp3dPoint(0,0,0),
new Pp3dPoint(0,0,0)];
lines = [ [0,1],[0,2],[1,2],[0,3]];
}
}
}package {
public class Pp3dPoint extends Pp3dObject{
private var _x:Number, _y:Number,_z:Number;
public function Pp3dPoint(x:Number = 0, y:Number = 0, z:Number = 0) {
super(x , y, z);
}
}
}package {
public class Pp3dObject {
private var _x:Number, _y:Number,_z:Number;
private var _rx:Number, _ry:Number,_rz:Number;
protected var _rxSin:Number, _rxCos:Number,_rySin:Number, _ryCos:Number,_rzSin:Number, _rzCos:Number;
public function Pp3dObject(ix:Number = 0, iy:Number = 0, iz:Number = 0) {
x = ix;
y = iy;
z = iz;
rotationX = rotationY = rotationZ = 0;
}
public function get x():Number { return _x }
public function get y():Number { return _y }
public function get z():Number { return _z }
public function set x(n:Number):void { _x = n }
public function set y(n:Number):void { _y = n }
public function set z(n:Number):void { _z = n }
public function get rotationX():Number { return _rx }
public function get rotationY():Number { return _ry }
public function get rotationZ():Number { return _rz }
public function set rotationX(n:Number):void {
_rx = n;
_rxSin = Math.sin(degToRad(n));
_rxCos = Math.cos(degToRad(n));
}
public function set rotationY(n:Number):void {
_ry = n;
_rySin = Math.sin(degToRad(n));
_ryCos = Math.cos(degToRad(n));
}
public function set rotationZ(n:Number):void {
_rz = n;
_rzSin = Math.sin(degToRad(n));
_rzCos = Math.cos(degToRad(n));
}
protected function rotateX(p:Pp3dPoint, dir:int = 1):Pp3dPoint {
var p2:Pp3dPoint = new Pp3dPoint();
p2.x = p.x;
p2.y = _rxCos * p.y - _rxSin * p.z;
p2.z = _rxCos * p.z+ _rxSin * p.y;
return p2
}
protected function rotateY(p:Pp3dPoint, dir:int = 1):Pp3dPoint {
var p2:Pp3dPoint = new Pp3dPoint();
p2.x = _ryCos * p.x - _rySin * p.z;
p2.y = p.y;
p2.z = _ryCos * p.z+ _rySin * p.x;
return p2
}
protected function rotateZ(p:Pp3dPoint, dir:int = 1):Pp3dPoint {
var p2:Pp3dPoint = new Pp3dPoint();
p2.x = _rzCos * p.x - _rzSin * p.y;
p2.y = _rzCos * p.y + _rzSin * p.x;
p2.z = p.z;
return p2
}
protected function radToDeg(n:Number):Number {
return n / Math.PI * 180;
}
protected function degToRad(n:Number):Number {
return n * Math.PI / 180;
}
static public function distance(p1:Pp3dObject, p2:Pp3dObject ):Number {
return Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) + (p1.z - p2.z) * (p1.z - p2.z));
}
}
}package {
import flash.geom.*;
public class Pp3dViewPoint extends Pp3dObject {
private var _fl:Number;
private var _zoom:Number;
public function Pp3dViewPoint(x:Number = 0, y:Number = 0, z:Number = -600) {
super(x,y,z);
zoom = 5;
focalLength = 200;
}
public function set focalLength(n:Number):void {
_fl = n;
}
public function set zoom(n:Number):void {
_zoom = n;
}
public function get focalLength():Number {
return _fl;
}
public function get zoom():Number {
return _zoom;
}
public function projectTo2d(p3d:Pp3dPoint):Pp2dPoint {
var p2d:Pp2dPoint = new Pp2dPoint();
var zero:Pp3dPoint = new Pp3dPoint();
p3d = new Pp3dPoint(p3d.x - x, p3d.y - y, p3d.z - z);
p3d = rotateX(p3d, -1);
p3d = rotateY(p3d, -1);
p3d = rotateZ(p3d, -1);
p2d.scale = _fl / p3d.z / 2 * zoom;
p2d.x = p3d.x * p2d.scale;
p2d.y = p3d.y * p2d.scale;
return p2d
}
}
}