By Zevan | January 9, 2009
Actionscript:
-
var canvas:BitmapData = new BitmapData(400, 400, false, 0xCCCCCC);
-
addChild(new Bitmap(canvas));
-
-
drawCircle(200,100, 50);
-
-
// y, y radius, color
-
function drawCircle(xp:Number,yp:Number, radius:Number, col:uint =0x000000):void {
-
var balance:int;
-
var xoff:int;
-
var yoff:int;
-
xoff=0;
-
yoff=radius;
-
balance=- radius;
-
-
while (xoff <= yoff) {
-
canvas.setPixel(xp+xoff, yp+yoff, col);
-
canvas.setPixel(xp-xoff, yp+yoff, col);
-
canvas.setPixel(xp-xoff, yp-yoff, col);
-
canvas.setPixel(xp+xoff, yp-yoff, col);
-
canvas.setPixel(xp+yoff, yp+xoff, col);
-
canvas.setPixel(xp-yoff, yp+xoff, col);
-
canvas.setPixel(xp-yoff, yp-xoff, col);
-
canvas.setPixel(xp+yoff, yp-xoff, col);
-
-
if ((balance += xoff++ + xoff)>= 0) {
-
balance-=--yoff+yoff;
-
}
-
}
-
}
The above demos a circle drawing algorithm. This will draw an outlined circle with no fill. This implementation doesn't use multiplication.
Using setPixel to draw primitive shapes can be a good learning experience. I found this basic implementation of the Bresenham Circle algorithm a few years back and lost the original link.... I dug around for a good hour trying to find the original but to no avail. So if someone recognizes this interesting implementation .... let me know
The original code was written in java I think.
If your curious. The standard implementation I keep finding online looks something like this:
Actionscript:
-
// ported from http://www.codeuu.com/Bresenham_Circle
-
function drawCircle(cx:Number, cy:Number, r:Number, col:uint):void{
-
var xp:int = 0, yp:int= r ;
-
var d:int = 3 - (2 * r);
-
-
while(xp <= yp){
-
-
canvas.setPixel(cx+xp,cy+yp,col);
-
canvas.setPixel(cx+yp,cy+xp,col);
-
canvas.setPixel(cx-xp,cy+yp,col);
-
canvas.setPixel(cx+yp,cy-xp,col);
-
canvas.setPixel(cx-xp,cy-yp,col);
-
canvas.setPixel(cx-yp,cy-xp,col);
-
canvas.setPixel(cx+xp,cy-yp,col);
-
canvas.setPixel(cx-yp,cy+xp,col);
-
-
if (d<0){
-
d += (4*xp)+6;
-
}else{
-
d += (4*(xp-yp))+10;
-
yp -= 1;
-
}
-
xp++;
-
}
-
-
}
I did a few speed tests against the first one that doesn't make use of multiplication and it is only ever so slightly faster....
By Zevan | January 8, 2009
Actionscript:
-
// tracing out large numbers will go into exponent notation
-
trace(1000000000000000000000000);
-
// outputs: 1e+24
-
-
var a:String = "1000000000000000000000009";
-
var b:String = "12000000000000000000000001";
-
-
// bigAdd function adds two large numbers
-
trace(bigAdd(a, b));
-
// outputs: 13000000000000000000000010
-
-
// unclear what regular addition is doing here:
-
trace(int(a) + int(b));
-
// outputs: -3758096384
-
-
function bigAdd(a:String, b:String):String{
-
var answer:String="";
-
var carry:int = 0;
-
var zeros:int = 0;
-
var i:int = 0;
-
var max:int = 0;
-
-
// obtain max variable and prepend zeros to the shortest string
-
if (a.length> b.length){
-
max = a.length;
-
zeros = max - b.length;
-
for (i= 0; i<zeros; i++) {
-
b = "0" + b;
-
}
-
}else if (b.length> a.length){
-
max = b.length;
-
zeros = max - a.length;
-
for (i= 0; i<zeros; i++) {
-
a = "0" + a ;
-
}
-
}else{
-
// a and b have same number of digets
-
max = a.length;
-
}
-
-
// add each character starting with the last (max - 1),
-
// carry the 1 if the sum has a length of 2
-
for (i = max - 1; i> -1; i--){
-
var sum:String = String(int(a.charAt(i)) + int(b.charAt(i)) + carry);
-
-
if (sum.length == 2){
-
answer = sum.charAt(1) + answer;
-
carry = 1;
-
}else{
-
carry = 0;
-
answer = sum + answer;
-
}
-
}
-
if (carry == 1){
-
answer = 1 + answer;
-
}
-
return answer;
-
}
This snippet demos a function called bigAdd(), which can be used to add very large numbers that the standard numerical datatypes (int, Number, etc) won't really work with. It uses a string based addition algorithm.
When I decided to write this snippet I dug around for awhile trying to find a nice elegant algorithm to port, something done without prepending zeros etc.... but I couldn't find one that suited my needs... so I just created this one from scratch. There's room for optimization and improvement but it works well enough for just playing around.
BigDecimal & BigInteger
A few months back I needed to do some programming with very large numbers. I dug around for awhile and eventually found out that java has a built in BigInteger andBigDecimal class.... I used java to write the program I had in mind, but thought it would be fun to eventually create something similar for ActionScript....
By Zevan | January 7, 2009
Actionscript:
-
trace(Math.pow((1+1/10000000),10000000));
-
-
trace(Math.E);
-
-
/*outputs :
-
-
2.7182816939803724
-
2.718281828459045
-
-
*/
E
2.7182818284590452353602874713526624977572470936999595749669676277240766303535
47594571382178525166427427466391932003059921817413596629043572900334295260595630
73813232862794349076323382988075319525101901157383418793070215408914993488416750
92447614606680822648001684774118537423454424371075390777449920695517027618386062
61331384583000752044933826560297606737113200709328709127443747047230696977209310
14169283681902551510865746377211125238978442505695369677078......
Posted in misc, one-liners | Also tagged flash |
By Zevan | January 6, 2009
Actionscript:
-
// this one-liner is good to know:
-
// Math.max(minValue, Math.min(maxValue, valueToClamp));
-
-
// wrapped in a function it looks like this:
-
const MIN:Number = 0;
-
const MAX:Number = 100;
-
-
function clamp(val:Number, min:Number = MIN, max:Number = MAX){
-
return Math.max(min, Math.min(max, val))
-
}
-
-
for (var i:int = 0; i<1000; i++){
-
var val:Number = Math.random()*1000 - 500;
-
// clamp the above random value between -100 and +100
-
trace(clamp(val, -100, 100));
-
}
Although I show a function implementation above, I use this technique inline a good deal. If there is some value that I need to clamp I'll often just "max min it":
Actionscript:
-
var val:Number = Math.random()*1000;
-
// clamp it - 0-100
-
trace(Math.max(0, Math.min(100, val));
Posted in misc, one-liners | Also tagged flash |