Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

879389 Posts in 32976 Topics- by 24364 Members - Latest Member: caraag31

May 24, 2013, 12:23:11 AM
TIGSource ForumsDeveloperTechnical (Moderators: Glaiel-Gamer, ThemsAllTook)The happy programmer room
Pages: 1 ... 143 144 [145] 146 147 ... 227
Print
Author Topic: The happy programmer room  (Read 264052 times)
Ashkin
Level 10
*****



View Profile
« Reply #2160 on: October 23, 2011, 03:08:29 AM »

Just compressed way too many lines of code into a couple of for loops! It makes CIRCLES.
Code:
var widthtracker:int = 3;//This is always 3- produces diamonds at larger sizes but whatever.
for (var Y:int = Math.round(y/8)-_radius; Y < Math.round(y/8)+_radius+1; Y++)
{
for (var X:int = Math.round(x/8)-((widthtracker-1)/2)-1; X <  Math.round(x/8)+((widthtracker-1)/2); X++)
{
registry.scenerymap.setTile(X, Y, 0);
registry.collisionmap.setTile(X, Y, 0);
registry.tilemap.setTile(X, Y, 0);
}

if (Y > Math.round(y/8))
{
widthtracker -= 2;
}
else if (Y < Math.round(y/8)-1)
{
widthtracker += 2;
}
}
Yeah, I probably could've found some circle-making code online. But it was fun to do it myself, and the feeling it gave me was awesome.
Logged
Nix
Level 10
*****



View Profile
« Reply #2161 on: October 23, 2011, 05:41:19 AM »

Dude. Just use sin and cos
Logged
rivon
Level 10
*****



View Profile
« Reply #2162 on: October 23, 2011, 07:47:41 AM »

Dude. Just use sin and cos
Exactly my thoughts... It would be much shorter and simpler...
Logged
Ashkin
Level 10
*****



View Profile
« Reply #2163 on: October 23, 2011, 01:50:30 PM »

Dude. Just use sin and cos
Exactly my thoughts... It would be much shorter and simpler...
Yeah but you see the problem here is that I'm awful at math.
Guess I'd better go look up how to use sin and cos to make circles... Man I suck.
Logged
mcc
Level 10
*****


glitch


View Profile WWW Email
« Reply #2164 on: October 23, 2011, 02:05:32 PM »

Parameters: Radius, Points, Centerx, Centery

For t=0 to Points
    theta = t/Points * 2 * pi
    x = Centerx + Radius*sin(theta)
    y = Centery + Radius*cos(theta)
    Plot(x,y)
Logged

My projects:<br />Games: Jumpman Retro-futuristic platforming iJumpman iPhone version Drumcircle PC+smartphone music toy<br />More: RUN HELLO
Ashkin
Level 10
*****



View Profile
« Reply #2165 on: October 23, 2011, 02:12:46 PM »

Parameters: Radius, Points, Centerx, Centery

For t=0 to Points
    theta = t/Points * 2 * pi
    x = Centerx + Radius*sin(theta)
    y = Centery + Radius*cos(theta)
    Plot(x,y)
I think I understand that... Radius is (obviously) how far the circle extends from the center, while centerx/y is the middle of the circle. But what is the Points variable? Droop
Logged
mcc
Level 10
*****


glitch


View Profile WWW Email
« Reply #2166 on: October 23, 2011, 02:16:34 PM »

Parameters: Radius, Points, Centerx, Centery

For t=0 to Points
    theta = t/Points * 2 * pi
    x = Centerx + Radius*sin(theta)
    y = Centery + Radius*cos(theta)
    Plot(x,y)
I think I understand that... Radius is (obviously) how far the circle extends from the center, while centerx/y is the middle of the circle. But what is the Points variable? Droop
"How many points of the circle do I draw?"

If you set Points to 4, you will draw a square/diamond

If you set Points to something large like 50 or 100 (preferably not larger than you need) it will look like a circle
Logged

My projects:<br />Games: Jumpman Retro-futuristic platforming iJumpman iPhone version Drumcircle PC+smartphone music toy<br />More: RUN HELLO
Ashkin
Level 10
*****



View Profile
« Reply #2167 on: October 23, 2011, 02:18:47 PM »

Parameters: Radius, Points, Centerx, Centery

For t=0 to Points
    theta = t/Points * 2 * pi
    x = Centerx + Radius*sin(theta)
    y = Centery + Radius*cos(theta)
    Plot(x,y)
I think I understand that... Radius is (obviously) how far the circle extends from the center, while centerx/y is the middle of the circle. But what is the Points variable? Droop
"How many points of the circle do I draw?"

If you set Points to 4, you will draw a square/diamond

If you set Points to something large like 50 or 100 (preferably not larger than you need) it will look like a circle
Oh, haha, I get it. So you'd need an infinite loop for a proper circle, but the higher the number, the smoother it is. Thanks mcc <3
Logged
Glaiel-Gamer
Moderator
Level 10
******


Stoleurface!


View Profile WWW Email
« Reply #2168 on: October 23, 2011, 02:37:40 PM »

Dude. Just use sin and cos

or this
http://en.wikipedia.org/wiki/Midpoint_circle_algorithm

which looks closer to what he already has than sin/cos (sin/cos are also expensive if performance matters)

especially if you're calculating sin/cos for EVERY POINT, you can/should do it once (with delta_theta which is 2*pi / points) and then do [copypasta from my own circle iteration]

Code:
gla::sincos((PI/2.0)/seg, sind, cosd); //sincos sets sind to sin(theta) and cosd to cos(thets), slight optimization in my implimentation to do both at the same time rather than one at a time
Vec2D edge = Vec2D::UP; //vector is (0, -1), scale it by radius if needed
  
for(int i = 0; i<=seg; i++){
  edge.rotate(sind, cosd);
  //circle point is edge.x, edge.y
}

...
...
...

void Vec2D::rotate(float sina, float cosa){
  float tx = x*cosa-y*sina;
  float ty = x*sina+y*cosa;
  x = tx;
  y = ty;
}

Logged

Nix
Level 10
*****



View Profile
« Reply #2169 on: October 23, 2011, 02:42:01 PM »

You're basically doing a matrix transform and calculating the transformation matrix once. I had a lot of fun playing with matrix transformations while making the lighting for Solar Reboot.
Logged
Ashkin
Level 10
*****



View Profile
« Reply #2170 on: October 23, 2011, 02:48:08 PM »

Oh dear, sin and cos do appear to be quite performance-heavy, especially if you're trying to make a full circle like my algorithm does, rather than just an outline. Honestly I don't see why I should change my algorithm when the other alternatives are more performance-heavy, but I'll try experimenting with the Midpoint circle algorithm that Glaiel posted. Although, honestly, I doubt I can understand it.

... I'm bad at programming. I don't even know what a floating point number is for, though I aim to remedy that right now.
Logged
mcc
Level 10
*****


glitch


View Profile WWW Email
« Reply #2171 on: October 23, 2011, 03:00:22 PM »

What I usually do on the performance issue is something like declare a global

cpVect onehundredpointsofacircle[100];

(where cpVect is a 2-vector) and then prepopulate it with circle values at startup. That means I call the trig functions 200 times at startup, then after that all circle point calculations are a single lookup. Nix/Glaiel's approach sounds good too though and under many situations would be more performant.
Logged

My projects:<br />Games: Jumpman Retro-futuristic platforming iJumpman iPhone version Drumcircle PC+smartphone music toy<br />More: RUN HELLO
Ashkin
Level 10
*****



View Profile
« Reply #2172 on: October 23, 2011, 03:16:01 PM »

What I usually do on the performance issue is something like declare a global

cpVect onehundredpointsofacircle[100];

(where cpVect is a 2-vector) and then prepopulate it with circle values at startup. That means I call the trig functions 200 times at startup, then after that all circle point calculations are a single lookup. Nix/Glaiel's approach sounds good too though and under many situations would be more performant.
So you're basically 'baking' in preset values so you have a lookup table rather than doing all of the calculations as they happen? That seems like it could be good for performance. But even with the calculations, as long as they take, my circle look... weird. It may be because I'm only doing them in a 7*7 or so space. That's why I feel my algorithm works better- I'll always be working in small sizes.
Logged
Tesla Shockwave
Level 0
*


View Profile
« Reply #2173 on: October 23, 2011, 04:29:45 PM »

Started C++ in college  Smiley
Logged
st33d
Guest
« Reply #2174 on: October 24, 2011, 02:52:18 AM »

What I usually do on the performance issue is something like declare a global

cpVect onehundredpointsofacircle[100];

(where cpVect is a 2-vector) and then prepopulate it with circle values at startup. That means I call the trig functions 200 times at startup, then after that all circle point calculations are a single lookup. Nix/Glaiel's approach sounds good too though and under many situations would be more performant.
So you're basically 'baking' in preset values so you have a lookup table rather than doing all of the calculations as they happen? That seems like it could be good for performance. But even with the calculations, as long as they take, my circle look... weird. It may be because I'm only doing them in a 7*7 or so space. That's why I feel my algorithm works better- I'll always be working in small sizes.

Um, there's always the Bresenham algorithms for these:

Code:
package com.nitrome.gfx {
/**
* Draws a filled pixelated circle to a Vector of pixels
*
* code is a trimmed version of the code found here:
* http://actionsnippet.com/?p=1658
*
* @author Aaron Steed, nitrome.com
*/

public function bresenhamCircle(x:int, y:int, radius:int, pixels:Vector.<uint>, width:int, height:int, col:uint = 0x00000000):void{

var xoff:int =0;
var yoff:int = radius;
var balance:int = -radius;
var i:int, p0:int, p1:int, w0:int, w1:int, index:int;
var size:int = width * height;

while(xoff <= yoff){
p0 = x - xoff;
p1 = x - yoff;
w0 = xoff + xoff;
w1 = yoff + yoff;

index = p0 + (y + yoff) * width;
for (i = 0; i < w0; i++){
index++;
if(index > -1 && index < size) pixels[index] = col;
}

index = p0 + (y - yoff) * width;
for (i = 0; i < w0; i++){
index++;
if(index > -1 && index < size) pixels[index] = col;
}

index = p1 + (y + xoff) * width;
for (i = 0; i < w1; i++){
index++;
if(index > -1 && index < size) pixels[index] = col;
}

index = p1 + (y - xoff) * width;
for (i = 0; i < w1; i++){
index++;
if(index > -1 && index < size) pixels[index] = col;
}

balance += xoff + xoff;
xoff++;
if (balance >= 0){
yoff--;
balance -= yoff + yoff;
}

}

}

}

Code:
package com.nitrome.gfx {
import flash.display.BitmapData;
/**
* Draws a Bresenham Ellipse.
*
* ported from:
* http://homepage.smc.edu/kennedy_john/belipse.pdf
*
* (if he mentioned it was written in Delphi in the paper it would have saved me some time)
*
* @author Aaron Steed, nitrome.com
*/
public function bresenhamEllipse(cx:int, cy:int, radiusX:int, radiusY:int, bitmapData:BitmapData, col:uint = 0x00000000):void{
var x:int, y:int;
var changeX:int, changeY:int;
var error:int;
var twoASquare:int, twoBSquare:int;
var stoppingX:int, stoppingY:int;

twoASquare = 2 * radiusX * radiusX;
twoBSquare = 2 * radiusY * radiusY;
x = radiusX;
y = 0;
changeX = radiusY * radiusY * (1 - 2 * radiusX);
changeY = radiusX * radiusX;
error = 0;
stoppingX = twoBSquare * radiusX;
stoppingY = 0;

while(stoppingX >= stoppingY){
bitmapData.setPixel32(cx + x, cy + y, col);
bitmapData.setPixel32(cx - x, cy + y, col);
bitmapData.setPixel32(cx - x, cy - y, col);
bitmapData.setPixel32(cx + x, cy - y, col);
y++;
stoppingY += twoASquare;
error += changeY;
changeY += twoASquare;
if(2 * error + changeX > 0){
x--;
stoppingX -= twoBSquare;
error += changeX;
changeX += twoBSquare;
}
}

x = 0;
y = radiusY;
changeX = radiusY * radiusY;
changeY = radiusX * radiusX * (1 - 2 * radiusY);
error = 0;
stoppingX = 0;
stoppingY = twoASquare * radiusY;

while(stoppingX <= stoppingY){
bitmapData.setPixel32(cx + x, cy + y, col);
bitmapData.setPixel32(cx - x, cy + y, col);
bitmapData.setPixel32(cx - x, cy - y, col);
bitmapData.setPixel32(cx + x, cy - y, col);
x++;
stoppingX += twoBSquare;
error += changeX;
changeX += twoBSquare;
if(2 * error + changeY > 0){
y--;
stoppingY -= twoASquare;
error += changeY;
changeY += twoASquare;
}
}
}

}

They're about the fastest method you're going to get. Or you could simply build a table if it's always small circles.
Logged
Pages: 1 ... 143 144 [145] 146 147 ... 227
Print
Jump to:  

Theme orange-lt created by panic