Rotating a circular disk

Does anyone have an algorithm or function to rotate a displayed circle. To turn it 360 degrees like a car-tire.
(It's needed to turn a turn-table in a model-railrod control program)
Last edited on
What graphics library are you using?
I'm using the integrated Graphics in my Borland C++ Builder
You can use rotation matrices for this.
http://en.wikipedia.org/wiki/Rotation_matrix
Thanks, xismn, for the answer. But I'm not in a postion to write a program from the info in this wikipedia article.
Why not?
You want to rotate it by 360 degrees? I think I have a very simple algorithm for you:
1
2
3
4
Circle Rotate360(Circle circle)
{
    return circle;
}


By the way:
Q: Why do they call it the Xbox 360?
A: Because you turn 360 degrees and walk away from it.
Last edited on
That's the dumbest thing I've ever heard about the XBox, and yet I keep hearing it.
@stewbond not sure if intentional.
@xismn
From the tone of his post, it's intentional. There are, however, people that actually think that 360 degrees ms an actual half rotation.
Yeah, it was a joke.
I also figured that my 360-degree rotation returning a copy of the original object way pretty funny too. Maybe I'm just having that kind of a night.
Last edited on
It was your one-liner alg. that gave away the XBox joke.
Ugh I'm totally out of it today, haha!
Yep, transformation matrices is definitely the way to go. You want to start by defining a Matrix class that encapsulates a 2x2 matrix and defines certain operations. Most importantly, rotation matrix construction, matrix inversion, and vector multiplication. you can have mine for free (TODO: vector multiplication):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class Matrix{
	double matrix[4];
public:
	Matrix(){
		this->matrix[0]=
		this->matrix[1]=
		this->matrix[2]=
		this->matrix[3]=0.0;
	}
	Matrix(double a,double b,double c,double d){
		this->matrix[0]=a;
		this->matrix[1]=b;
		this->matrix[2]=c;
		this->matrix[3]=d;
	}
	double determinant() const{
		return this->matrix[0]*this->matrix[3]-this->matrix[1]*this->matrix[2];
	}
	Matrix inverse() const{
		double a=1.0/this->determinant();
		return Matrix(
			a*this->matrix[3],
			a*-this->matrix[1],
			a*-this->matrix[2],
			a*this->matrix[0]
		);
	}
	Matrix operator*(const Matrix &m) const{
		return Matrix(
			this->matrix[0]*m.matrix[0]+this->matrix[1]*m.matrix[2],
			this->matrix[0]*m.matrix[1]+this->matrix[1]*m.matrix[3],
			this->matrix[2]*m.matrix[0]+this->matrix[3]*m.matrix[2],
			this->matrix[2]*m.matrix[1]+this->matrix[3]*m.matrix[3]
		);
	}
	const double &operator[](unsigned i)const{ return this->matrix[i]; }
	static Matrix rotation(double alpha){
		return Matrix(cos(alpha),-sin(alpha),sin(alpha),cos(alpha));
	}
	static Matrix scale(double x,double y){
		return Matrix(x,0,0,y);
	}
	static Matrix shear(double x,double y){
		return Matrix(1,x,y,1);
	}
};

So, say you want to rotate a bitmap by theta radians. You'd start out by constructing your forward matrix:
 
Matrix forward_matrix = Matrix::rotation(theta);
The forward matrix corresponds to a linear transformation that rotates a 2D vector about the origin by theta radians. You can apply the linear transformation onto the vector by multiplying it by the matrix (v2 = M * v1).

Now you'l need to know how big the destination bitmap needs to be. That's fairly easy. Suppose you already have the corners of the source in four vectors:
 
Vector v[4];
You simply transform them with the forward_matrix:
1
2
for (int a = 0; a < 4; a++)
	v = forward_matrix * v;
Now get the minima and maxima of each component for the four vectors. The difference between the minimum and maximum for a component is how large the destination needs to be along that axis.

A forward transformation would be inefficient. Instead, you'll want to be able to take a pixel in the destination bitmap and figure out which pixel(s) from the source to copy. For that, you need the backward matrix, which is the inverse of the forward matrix.
 
Matrix backward_matrix = forward_matrix.inverse();
Note in the code that it's not possible to invert a matrix whose determinant is zero. All rotation matrices have a non-zero determinant, though.

You now have everything you need to start copying pixels.
1
2
3
4
5
6
7
8
9
for (int y = 0; y < destination.height(); y++){
	for (int x = 0; x < destination.width(); x++){
		Vector destination_coord(x, y);
		Vector source_coord = backward_matrix * destination_coord;
		if (!source.bounding_rectangle.contains(source_coord))
			continue;
		destination.copy_onto(source.pixel(source_coord), destination_coord);
	}
}
Helio's post reminds me of Quaternions which is a great concept in mathematics. Normal vectors, points, or matricies can take quite a bit of power to rotate. However, they could be stored as quaternions which are stored in such a way, that manipulative math is very simple and easy on your processor. Try those out.
Topic archived. No new replies allowed.