Example of applying effect of light by computing the angle between the plane surface and the light.
To determine the angle of the plane, two vectors that represent the two sides of it are needed. The cross product, which is a vector perpendicular to the both of the vectors, can be calculated using the formula below.
Vector3D object provides convenient methods to do this process, crossProduct() and angleBetween(), which returns a cross product of two vectors and angle between two vectors, respectively.
A×B = [(a2 * b3 - a3 * b2) * (a3 * b1 - a1 * b3) * (a1 * b2 - a2 * b1)]
for any two vectors A = [a1 a2 a3] and B[b1 b2 b3]
package {
import flash.display.*;
import flash.geom.*;
import flash.events.*
public class Main extends Sprite {
private var canvas:Sprite;
private var vecs:Vector.<Vector3D>;
private var mtr3d:Matrix3D;
private var lightVec:Vector3D = new Vector3D(0,0,-1);
private var color:uint = 0xfff000;
public function Main() {
vecs = new Vector.<Vector3D>();
vecs.push(new Vector3D(-100,-100,0));
vecs.push(new Vector3D(100,-100,0));
vecs.push(new Vector3D(100,100,0));
vecs.push(new Vector3D(-100,100,0));
mtr3d = new Matrix3D();
mtr3d.prependRotation(1,Vector3D.Y_AXIS);
addChild(canvas = new Sprite());
canvas.x = stage.stageWidth / 2;
canvas.y = stage.stageHeight / 2;
canvas.z = 1;
addEventListener(Event.ENTER_FRAME, h_enterFrame);
}
public function h_enterFrame(evt:Event):void {
var i:uint;
lightVec = new Vector3D(canvas.mouseX, canvas.mouseY, -100);
// rotate
for (i = 0; i < vecs.length; i ++) {
vecs[i] = mtr3d.transformVector(vecs[i])
}
// angle between the plane and the light
var v1:Vector3D = vecs[0].subtract(vecs[1]);
var v2 :Vector3D = vecs[0].subtract(vecs[3]);
var cp:Vector3D = v1.crossProduct(v2);
var angle:Number = Vector3D.angleBetween(cp, lightVec);
if (angle > Math.PI / 2) { angle = Math.PI - angle };
// brightness
var brightness:Number = 1 - angle / Math.PI * 0.7;
var r:uint = color >> 16 & 0xff;
var g:uint = color >> 8 & 0xff;
var b:uint = color & 0xff;
r *= brightness;
g *= brightness;
b *= brightness;
var tColor:uint = r << 16 | g << 8 | b;
// draw
var p:Point;
var gr:Graphics = canvas.graphics;
gr.clear();
gr.beginFill(tColor);
for (i = 0; i < vecs.length; i ++) {
p = getPoint2d(vecs[i]);
if (i == 0) {
gr.moveTo(p.x, p.y);
} else {
gr.lineTo(p.x, p.y);
}
}
}
public function getPoint2d(v:Vector3D):Point {
var p:Point = canvas.local3DToGlobal(v);
return canvas.globalToLocal(p);
}
}
}