By Zevan | November 29, 2009
Actionscript:
-
// print some floats as fractions
-
printFraction(0.5);
-
printFraction(0.75);
-
printFraction(0.48);
-
-
// try something a little more complex
-
var float:Number = 0.98765432;
-
trace("\na more complex example:");
-
printFraction(float);
-
var frac:Array = asFraction(float);
-
trace("double check it:");
-
trace(frac[0] + "/" + frac[1] +" = " + frac[0] / frac[1]);
-
-
/* outputs:
-
0.5 = 1/2
-
0.75 = 3/4
-
0.48 = 12/25
-
-
a more complex example:
-
0.98765432 = 12345679/12500000
-
double check it:
-
12345679/12500000 = 0.98765432
-
*/
-
-
-
function printFraction(n:Number):void{
-
var frac:Array = asFraction(n);
-
trace(n + " = " + frac[0] + "/" + frac[1]);
-
}
-
-
// takes any value less than one and returns an array
-
// with the numerator at index 0 and the denominator at index 1
-
function asFraction(num:Number):Array{
-
var decimalPlaces:int = num.toString().split(".")[1].length;
-
var denom:Number = Math.pow(10, decimalPlaces);
-
return reduceFraction(num * denom, denom);
-
}
-
-
// divide the numerator and denominator by the GCF
-
function reduceFraction(numerator:int, denominator:Number):Array{
-
// divide by the greatest common factor
-
var divisor:int = gcf(numerator, denominator);
-
if (divisor){
-
numerator /= divisor;
-
denominator /= divisor;
-
}
-
return [numerator, denominator];
-
}
-
-
// get the greatest common factor of two integers
-
function gcf(a:int, b:int):int{
-
var remainder:int;
-
var factor:Number = 0;
-
var maxIter:int = 100;
-
var i:int = 0;
-
while (1){
-
if (b> a){
-
var swap:int = a;
-
a = b;
-
b = swap;
-
}
-
remainder = a % b;
-
a = b;
-
b = remainder
-
if (remainder == 0){
-
factor = a;
-
break;
-
}else if (remainder==1){
-
break;
-
}else if (i> maxIter){
-
trace("failed to calculate gcf");
-
break;
-
}
-
i++;
-
}
-
return factor;
-
}
This snippet contains a few functions for calculating fractions based on float values. Writing this brought back some memories from grade school math.
Posted in Math, misc | Tagged actionscript, as3, flash |
By Zevan | November 28, 2009
Actionscript:
-
trace(gcf(75,145));
-
-
// outputs 5
-
-
function gcf(a:int, b:int):int{
-
var remainder:int;
-
var factor:Number = 0;
-
while (1){
-
if (b> a){
-
var swap:int = a;
-
a = b;
-
b = swap;
-
}
-
remainder = a % b;
-
a = b;
-
b = remainder
-
if (remainder == 0){
-
factor = a;
-
break;
-
}else if (remainder==1){
-
-
break;
-
}
-
}
-
return factor;
-
}
I was messing around with Egyptian Fractions and found myself in need of some interesting functions. The first function I realized I would be needing was for a greatest common factor (GCF or GCD).
The above snippet is a quick implementation of Euclid's algorithm. It will return 0 if no GCF is found...
I wrote a few helper functions while working with Egyptian fractions... will post them over the next few days.
Posted in Math | Tagged actionscript, as3, flash |
By Zevan | November 27, 2009
Actionscript:
-
egyptianMultiply(12, 99);
-
-
// trace(12 * 99) // test to make sure it works
-
-
/* outputs:
-
/64 768
-
/32 384
-
16 192
-
8 96
-
4 48
-
/2 24
-
/1 12
-
---
-
1188
-
*/
-
-
-
function egyptianMultiply(valueA:Number, valueB:Number):void {
-
-
var left:Array = [];
-
var right:Array = []
-
-
// swap if valueB is smaller than value A
-
if (valueB <valueA){
-
var swap:int = valueB;
-
valueB = valueA;
-
valueA = swap;
-
}
-
-
// create left and right columns
-
var currentLeft:int = 1;
-
var currentRight:int = valueA;
-
-
while (currentLeft <valueB){
-
left.push(currentLeft);
-
right.push(currentRight);
-
currentRight += currentRight;
-
currentLeft += currentLeft;
-
}
-
-
-
// add up the right column based on the left
-
currentLeft = 0;
-
var rightSum:int;
-
var leftSum:int;
-
var i:int = left.length - 1;
-
-
while (currentLeft != valueB){
-
-
leftSum = currentLeft + left[i];
-
// if the next number causes the sum
-
// to go above valueB, skip it
-
if (leftSum <= valueB){
-
currentLeft = leftSum;
-
rightSum += right[i];
-
trace("/" + left[i] + " " + right[i]);
-
} else {
-
trace(" " + left[i] + " " + right[i]);
-
}
-
i--;
-
}
-
trace("---");
-
trace(rightSum);
-
}
Someone mentioned egyptian multiplication to me yesterday... So read a little about it here and whipped up this example. For some reason I decided to do it in processing ... once it worked I ported it to ActionScript.
The above link describing the technique I used is from http://www.jimloy.com/... I haven't spent much time digging around the site, but it appears to have some pretty nice stuff on it...
If you're curious, here is the original processing version:
JAVA:
-
-
-
-
int valueA = 10;
-
int valueB = 8;
-
-
if (valueB <valueA){
-
int swap = valueB;
-
valueB = valueA;
-
valueA = swap;
-
}
-
-
int currentLeft = 1;
-
int currentRight = valueA;
-
while (currentLeft <valueB){
-
left.add(currentLeft);
-
right.add(currentRight);
-
currentRight += currentRight;
-
currentLeft += currentLeft;
-
}
-
-
currentLeft = 0;
-
-
int result = 0;
-
int i = left.size() - 1;
-
while (currentLeft != valueB){
-
-
int temp
= currentLeft
+ (Integer) left.
get(i
);
-
if (temp <= valueB){
-
-
currentLeft = temp;
-
-
println("/" + left.get(i) + " " + right.get(i));
-
} else {
-
println(" " + left.get(i) + " " + right.get(i));
-
}
-
-
i--;
-
}
-
println("---");
-
println(result);
After writing, this I took a look at the wikipedia entry... I also found myself on this short page about a scribe called Ahmes. (I recommend reading this if you are interested in PI)
By Zevan | November 25, 2009
Actionscript:
-
var container:Sprite = new Sprite();
-
container.x = stage.stageWidth / 2;
-
container.y = stage.stageHeight / 2;
-
addChild(container);
-
-
var redBox:Sprite = new Sprite();
-
redBox.graphics.beginFill(0xFF0000);
-
redBox.graphics.drawRect(-50,-250,100,500);
-
redBox.rotationZ = 10;
-
container.addChild(redBox);
-
-
var logos:Array = []
-
var elements:Array = [];
-
elements.push({element:redBox, z:0});
-
-
// add the logos
-
for (var i:int = 0; i<6; i++){
-
var logoContainer:MovieClip = new MovieClip();
-
var logoText:TextField = new TextField();
-
logoText.defaultTextFormat = new TextFormat("_sans", 50);
-
logoText.text = "LOGO";
-
logoText.autoSize = "left";
-
logoText.selectable= false;
-
-
logoText.x = -logoText.width / 2;
-
logoText.y = -logoText.height / 2;
-
logoContainer.addChild(logoText);
-
logoText.backgroundColor = 0xFFFFFF;
-
-
container.addChild(logoContainer);
-
logos.push(logoContainer);
-
elements.push({element:logoContainer, z:0});
-
}
-
-
var ang:Number = -Math.PI / 2;
-
var rotationSpeed:Number = 0.05;
-
addEventListener(Event.ENTER_FRAME, onLoop);
-
function onLoop(evt:Event):void {
-
-
var dx:Number = (mouseY - stage.stageHeight / 2) / 10;
-
var dy:Number = (mouseX - stage.stageWidth / 2) / 10;
-
container.rotationX += (dx - container.rotationX) / 4;
-
container.rotationY += (dy - container.rotationY) / 4;
-
-
ang += rotationSpeed;
-
for (var i:int = 0; i<logos.length; i++){
-
var logo:Sprite = logos[i];
-
logo.x = 150 * Math.cos(ang + i);
-
logo.z = 150 * Math.sin(ang + i);
-
logo.alpha = 1 - logo.z / 200;
-
logo.rotationY = -Math.atan2(logo.z, logo.x) / Math.PI * 180 - 90;
-
}
-
-
// z-sort
-
for (i = 0; i<elements.length; i++){
-
elements[i].z = elements[i].element.transform.getRelativeMatrix3D(this).position.z;
-
}
-
-
elements.sortOn("z", Array.NUMERIC | Array.DESCENDING);
-
for (i = 0; i<elements.length; i++) {
-
container.addChild(elements[i].element);
-
}
-
}
A student of mine was having trouble creating a 3D logo for a client. I created this snippet to help explain how some of the fp10 3D stuff works.... z-sorting etc... The code could be optimized a bit... but it works nicely...
Have a look at the swf...