Simple Matrix Rotation

M

MB

Hello,
I am trying to rotate the following matrix by 90 degrees.

1 2 3
4 5 6
7 8 9

By multiplying each co-ordinate by the matrix:
cos(90) sin(90)
-sin(90) cos(90)

I am using the following code:

#include <math.h>

int main() {
// Declare variables
int x,y,new_x, new_y;

// Declare matrices
int new_matrix[4][4]; // Working with first index at 1 not 0
int old_matrix[4][4];

// Populate matrix
old_matrix[1][1] = 1;
old_matrix[2][1] = 2;
old_matrix[3][1] = 3;
old_matrix[1][2] = 4;
old_matrix[2][2] = 5;
old_matrix[3][2] = 6;
old_matrix[1][3] = 7;
old_matrix[2][3] = 8;
old_matrix[3][3] = 9;

// Loop thorugh matrix
for (y=1; y<4; y++) {
for (x=1; x<4; x++) {
// Rotate co-ordinates by mutlipling co-ords by rotation matrix
new_x = ((x*cos(90)) - (y*sin(90)));
new_y = ((x*sin(90)) + (y*cos(90)));

// Copy pre-rotated values to new matrix using new co-ords
new_matrix[x][y] = old_matrix[new_x][new_y];

// Print out the new co-ordinates
printf("(%d,%d) ", new_x, new_y);
}
printf("\n");
}
return 0;
}

The output is coming out as:
(-1,0) (-1,1) (-2,2)
(-2,0) (-2,0) (-3,1)
(-3,0) (-3,0) (-4,1)

Can anyone see where I am going wrong?

Thank you,
Martin
 
W

Walter Roberson

By multiplying each co-ordinate by the matrix:
cos(90) sin(90)
-sin(90) cos(90)

sin() and cos() take inputs in radians, not degrees.

Your code could pre-compute the sin() and cos() values instead of
recomputing them at each step.

If this is a full routine rather than just something leading up to
a more generalized rotation routine, then you should apply
elementary sin() and cos() reductions, to form the matrix
{ {0, 1}, {-1, 0} } ... which in turn would allow you to simplify your
code.

You are using printf() but you do not include <stdio.h> .
 
M

MB

Thanks for your speedy reponse. It works now. Also, thanks for the
optimisation advice.

p.s. #include <stdio.h> was cropped when I cut and paste the code.
 
P

pete

Hello,
I am trying to rotate the following matrix by 90 degrees.

1 2 3
4 5 6
7 8 9

By multiplying each co-ordinate by the matrix:
cos(90) sin(90)
-sin(90) cos(90)

I am using the following code:

#include <math.h>

Wrong header
int main() {

Obsolete declaration
// Declare variables

Pointless comment
int x,y,new_x, new_y;

// Declare matrices
int new_matrix[4][4];
// Working with first index at 1 not 0
Why?

// Loop thorugh matrix
for (y=1; y<4; y++) {
for (x=1; x<4; x++) {
// Rotate co-ordinates by mutlipling co-ords by rotation matrix
new_x = ((x*cos(90)) - (y*sin(90)));
new_y = ((x*sin(90)) + (y*cos(90)));

// Copy pre-rotated values to new matrix using new co-ords
new_matrix[x][y] = old_matrix[new_x][new_y];

// Print out the new co-ordinates
printf("(%d,%d) ", new_x, new_y);
}
printf("\n");
}
return 0;
}

The output is coming out as:
(-1,0) (-1,1) (-2,2)
(-2,0) (-2,0) (-3,1)
(-3,0) (-3,0) (-4,1)

Can anyone see where I am going wrong?

Looks like pretty much everywhere.
I probably don't understand how you're supposed to rotate
the matrix, but just rotating it, isn't that complicated.

/* BEGIN new.c output */

1 2 3
4 5 6
7 8 9

7 4 1
8 5 2
9 6 3

/* END new.c output */



/* BEGIN new.c */

#include <stdio.h>

#define SIDE 3

int main(void)
{
int x, y, new_x, new_y, count;
int new_matrix[SIDE][SIDE];
int old_matrix[SIDE][SIDE];

puts("/* BEGIN new.c output */\n");
count = 1;
for (y = 0; y != SIDE; ++y) {
for (x = 0; x != SIDE; ++x) {
old_matrix[x][y] = count++;
}
}
for (y = 0; y != SIDE; ++y) {
for (x = 0; x != SIDE; ++x) {
new_x = SIDE - 1 - y;
new_y = x;
new_matrix[new_x][new_y] = old_matrix[x][y];
printf("%2d ", old_matrix[x][y]);
}
putchar('\n');
}
putchar('\n');
for (y = 0; y != SIDE; ++y) {
for (x = 0; x != SIDE; ++x) {
printf("%2d ", new_matrix[x][y]);
}
putchar('\n');
}
puts("\n/* END new.c output */");
return 0;
}

/* END new.c */
 
K

Keith Thompson

pete said:
(e-mail address removed) wrote: [...]
By multiplying each co-ordinate by the matrix:
cos(90) sin(90)
-sin(90) cos(90)

I am using the following code:

#include <math.h>

Wrong header

No, he's using the sin() and cos() functions, so he needs <math.h>.
(He's using them both incorrectly and unnecessarily, so he doesn't
*really* need <math.h>, but it's required for his code as posted.)

Obsolete declaration

Not really. Empty parentheses in a function declaration mean that the
function takes an indeterminate number and type of arguments, but this
is a definition, so we know it takes no arguments. But of course
"int main(void)" is preferred, both because it's more explicit and
because it avoids this kind of question.
 
T

Tim Rentsch

Hello,
I am trying to rotate the following matrix by 90 degrees.

1 2 3
4 5 6
7 8 9

By multiplying each co-ordinate by the matrix:
cos(90) sin(90)
-sin(90) cos(90)

I am using the following code: [snip]

Can anyone see where I am going wrong?

First, you're asking in the wrong newsgroup. Even
though your program is written in C, the question
you're asking is about a C program and not about
the C language. The comp.lang.c newsgroup is for
discussion about the C language, not about C programs
(unless they are being used to illustrate discussion
about the language).

Second, it isn't clear what you want. Do you mean
to rotate the numerical values of the matrix,
resulting in

3 6 9
2 5 8
1 4 7

or do you mean to transform the matrix, considered
as a linear transformation, by a rotation about
some axis? If so then which axis?

So, I suggest:

Figure out what your question is; try to find a
way to state it clearly (and, if possible, succinctly,
but above all clearly); post it in a newsgroup that
addresses programming issues rather than language issues.
 
T

Tim Rentsch

K

Keith Thompson

Keith Thompson said:
pete said:
(e-mail address removed) wrote: [...]
int main() {

Obsolete declaration

Not really. Empty parentheses in a function declaration mean that the
function takes an indeterminate number and type of arguments, but this
is a definition, so we know it takes no arguments. But of course
"int main(void)" is preferred, both because it's more explicit and
because it avoids this kind of question.

"Indeterminate" wasn't the best word to use here.

Here's what the standard says, C99 6.7.5.3p14:

An identifier list declares only the identifiers of the parameters
of the function. An empty list in a function declarator that is
part of a definition of that function specifies that the function
has no parameters. The empty list in a function declarator that is
not part of a definition of that function specifies that no
information about the number or types of the parameters is
supplied.

A footnote points to "Future language directions", 6.11.6:

The use of function declarators with empty parentheses (not
prototype-format parameter type declarators) is an obsolescent
feature.

The standard even uses "int main()" in an example (6.7.5.3p20,
example 4).
 
T

tedu

Keith said:
A footnote points to "Future language directions", 6.11.6:

The use of function declarators with empty parentheses (not
prototype-format parameter type declarators) is an obsolescent
feature.

does this mean
void a();
is ok and
void b() { }
is not ok? or iow, what is a "prototype-format parameter type
declarator"?
 
K

Keith Thompson

tedu said:
does this mean
void a();
is ok and
void b() { }
is not ok? or iow, what is a "prototype-format parameter type
declarator"?

Note that "obsolescent" does not mean "not ok". An obsolescent
feature is one that's supported by the current standard (support is
absolutely required for any conforming implementation), but that may
be removed in a future standard.

There is never a good reason to use empty parentheses in a function
declaration or definition in C, unless you're concerned about
compatibility with ancient compilers. The above is better written as:

void a(void);
void b(void) { }

The forms with empty parentheses are legal, but they may become
illegal in a future standard. The declaration
void a();
does not specify the number or type of any parameters, making it
difficult to diagnose errors in calls. A call like a(42) invokes
undefined behavior. With a proper prototype, the error will be
diagnosed.

If the empty parentheses occur as part of a function definition, it's
clear from the definition that there are no parameters. I'm actually
not sure whether the compiler is required to diagnose incorrect calls
in this case; I don't *think* it is. In the case of main(), declaring
int main() { ... }
won't cause any problems unless you have an incorrect recursive call
to main().

In pre-ANSI C, the usual definition of main() was:
main(argc, argv)
int argc;
char **argv;
{n
...
}

with the int return type being implicit.

<OT>
In C++, empty parentheses mean that the function takes no arguments;
"void a()" in C++ means the same thing as "void a(void)" in C. The
use of "void" to denote an empty argument list is necessary in C to
avoid ambiguity with old-style declarations; C++ never supported
old-style declarations, so this wasn't necessary. I think C++ still
allows "void a(void)" for compatibility with C. If you just code
in one language or the other, you don't need to worry about this.
</OT>
 
P

pete

Keith said:
Keith Thompson said:
pete said:
(e-mail address removed) wrote: [...]
int main() {

Obsolete declaration

Not really.
A footnote points to "Future language directions", 6.11.6:

The use of function declarators with empty parentheses (not
prototype-format parameter type declarators) is an obsolescent
feature.

That's what I'm talking about.
The standard even uses "int main()" in an example (6.7.5.3p20,
example 4).

Poor choice on their part.
 
M

Mark McIntyre

On Fri, 4 Nov 2005 16:51:11 +0000 (UTC), in comp.lang.c ,
sin() and cos() take inputs in radians, not degrees.

Your code could pre-compute the sin() and cos() values instead of
recomputing them at each step.

er, you can write down the values for that matter....
 
J

Jordan Abel

Note that "obsolescent" does not mean "not ok". An obsolescent
feature is one that's supported by the current standard (support is
absolutely required for any conforming implementation), but that may
be removed in a future standard.

There is never a good reason to use empty parentheses in a function
declaration or definition in C, unless you're concerned about
compatibility with ancient compilers. The above is better written as:

void a(void);
void b(void) { }

The forms with empty parentheses are legal, but they may become
illegal in a future standard. The declaration
void a();
does not specify the number or type of any parameters, making it
difficult to diagnose errors in calls. A call like a(42) invokes
undefined behavior. With a proper prototype, the error will be
diagnosed.

Am I the only one who actually read the quoted paragraph? it says that

void a();

is obsolescent, and

void b() { ... }

is not.
 
N

Netocrat

Netocrat said:
(e-mail address removed) wrote: [...]
int main() {

Obsolete declaration

Not really.

6.11.4 Function declarators

[#1] The use of function declarators with empty parentheses
(not prototype-format parameter type declarators) is an
obsolescent feature.

(N869)

Obsolescent doesn't mean the same thing as obsolete. Look it
up.

Right, but it's important to know that the standard discourages the use of
this feature, and in contradicting pete's statement without mention of
this clause I felt that Keith's post was incomplete or even misleading,
although his later posts have amended the omission.

I have a copy but I find the plain text/html access to N869 easier to
navigate and search than the pdf of N1124.

On that matter, the domain that hosts the drafts I usually access has
recently stopped responding - does anyone know whether dev.unicals.com is
permanently down, moved or only temporarily down? I didn't save local
copies of their html-format drafts and they were great to work with.
 
T

Tim Rentsch

Netocrat said:
Netocrat said:
[...]
int main() {

Obsolete declaration

Not really.

6.11.4 Function declarators

[#1] The use of function declarators with empty parentheses
(not prototype-format parameter type declarators) is an
obsolescent feature.

(N869)

Obsolescent doesn't mean the same thing as obsolete. Look it
up.

Right, but it's important to know that the standard discourages the use of
this feature, and in contradicting pete's statement without mention of
this clause I felt that Keith's post was incomplete or even misleading,
although his later posts have amended the omission.

In that case wouldn't it have been better to say

"It's true that it isn't obsolete, but it is obsolescent."

rather than, or perhaps just before, quoting the paragraph?
Otherwise people might think you're confusing the two terms,
or confuse them themselves.

I have a copy but I find the plain text/html access to N869 easier to
navigate and search than the pdf of N1124.

Oh good. In that case could you please use the more up-to-date
section numbers in n1124 when posting (even if you prefer to use
N869 for your own searching/navigation)? I'm sure it would be
appreciated if you did.
 
T

Tim Rentsch

[context: function declarations/definitions with empty parentheses]
The forms with empty parentheses are legal, but they may become
illegal in a future standard. The declaration
void a();
does not specify the number or type of any parameters, making it
difficult to diagnose errors in calls. A call like a(42) invokes
undefined behavior. With a proper prototype, the error will be
diagnosed.

If the empty parentheses occur as part of a function definition, it's
clear from the definition that there are no parameters. I'm actually
not sure whether the compiler is required to diagnose incorrect calls
in this case; I don't *think* it is.

It's clear (even if it isn't obvious) that the Standard intends that
function definitions that have empty parentheses not be considered
prototypes (which means subsequent calls be treated just the same as
if there were only a declaration without any parameter information.

That doesn't match what the definition of prototype says, which is
that a prototype is "a declaration of a function that declares the
types of its parameters". A function definition written with empty
parentheses specifies that it has no parameters, and since it has no
parameters, every parameter of the function has its type declared by
the function declaration. Ergo, a function definition with empty
parentheses _should_ be considered a prototype since it declares the
types of its parameters, but what the Standard says and what it
means to say are different in this case.

It would be nice if wording in the Standard could be cleaned
up to get rid of logical inconsistencies like the one above.

In the case of main(), declaring
int main() { ... }
won't cause any problems unless you have an incorrect recursive call
to main().

Or an incorrect call to main() that isn't recursive, which is also
possible.
 
K

Keith Thompson

Tim Rentsch said:
Or an incorrect call to main() that isn't recursive, which is also
possible.

The only way I can think of to do that (barring an error in the
calling environment) is to have a call to main() in a function
registered via atexit(), and to terminate the program via a return
statement or reaching the closing '}' of the main function rather than
via exit(). (If the program terminates via exit(), execution of the
main() function doesn't terminate until exit() finishes, a subtlety
that can also affect atexit()-registered functions that refer to local
variables of main().)

Anyone who writes such code, of course, *should* suffer literal nasal
demons.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top