# Need help reducing an equation, math wiz's welcome. =)

This is a discussion on Need help reducing an equation, math wiz's welcome. =) within the C++ Programming forums, part of the General Programming Boards category; Heya guys, I've been busy! I've been cranking out simple 3D C++ apps that my girlfriend's kids love. I made ...

1. ## Need help reducing an equation, math wiz's welcome. =)

Heya guys, I've been busy! I've been cranking out simple 3D C++ apps that my girlfriend's kids love. I made a pong clone and now I'm working on a maze game, etc etc. Lots of fun.
Here's the trouble! 3D graphics = math. I'm a better programmer than arithmetician.

Code:
`((14 - (int)(13.8 - ((float)y / 35.217)))*50)+((int)(-25.0 + ((float)x / 34.7)) + 25)`
How can I reduce/simplify this?

What it does? Takes the x and y coordinates from OpenGL's "glutMotionFunc" - and translates them to object space coordinates some -30Z units in the distance. The x and y are serialized into a linear one dimensional array of 1,400 3-float structures. This array can be saved and loaded from disk like lightning, which is hot... but then getting it back into X and Y (adjusted from two positive coordinates (gotten by a modulus 50, and a subsequent divide 50) into a 0,0 signed coored.... omg... I digress.

I can always post some source. I'm NOT gonna do this way next time, and I learned alot. But man, 3 days to get this solution. The key was finally inverting the Y coord at the end of the process. Anyhow... relevant code for the sick freaks like me:

Code Produced here: [Edited, wrecked, I'm tired, sorry]
Code:
```static void motion(int x, int y)
{
cursorPosX = -25.0 + ((float)x / 34.7);
cursorPosY = 13.8 - ((float)y / 35.217);

clog << "Window Coordinates in Pixels with top left origin: ";
clog << "x: " << x << " y: " << y << endl;
clog << "Screen space coordinates with center origin: ";
clog << "x: " << cursorPosX << " y: " << cursorPosY << endl;
clog << "Formulation board coordinates from top-left: ";
clog << "x:" << (int)cursorPosX + 25 << " y: " << 14 - (int)cursorPosY << endl;

boardX = (int)cursorPosX + 25;
boardY = 14 - (int)cursorPosY;
int square = (boardY*50)+boardX;

cout << boardX << " " << boardY << " " << square
<< " \\ " << (square % 50) << " " << (square / 50 )
<< "   [" << (square % 50)-25 << " " << -((square / 50 )-14) << "]" << endl;

board[square] = colorTable(currentColor);
}```
And here's the final, compact, Linus Torvalds would shoot me, over simplification, noob, product:
Code:
```static void motion(int x, int y)
{
cursorPosX = (-25.0 + ((float)x / 34.7));
cursorPosY = (13.8 - ((float)y / 35.217));
board[((14 - (int)(13.8 - ((float)y / 35.217)))*50)+((int)(-25.0 + ((float)x / 34.7)) + 25)] = colorTable(currentColor);
}```
Which is why I need help reducing that badboy on the last line.

Thank you if any spare time or effort. You gurus inspire me.

M. Richard Tober

2. By the way, I've actually improved in skill, not all my code is wierd and convoluted - here's a templated function that takes a one dimentional array, it's size in elements, and a string filename - and saves it to a file! And the read one too.

Note: I use this in my custom *.hpp toolbox header, so the names are qualified.

Code:
```template <class T> bool readArray(T *array, unsigned long arraySize, std::string fileName)
{
std::ifstream file(fileName.c_str(), std::ios::binary);
if (!file.is_open()) {
std::cerr << "Unable to open \"" << fileName << "\"." << std::endl;
return false;
} else {
std::clog << "\"" << fileName << "\" opened successfully." << std::endl;
std::clog << "Reading " << arraySize *sizeof(T) << " bytes." << std::endl;
if (file.fail()) {
std::cerr << "Read operation failed." << std::endl;
file.clear();
return false;
} else {
std::clog << "Read " << file.gcount() << " bytes." << std::endl;
}
std::clog << "Closing \"" << fileName << "\"." << std::endl;
file.close();
}
return true;
}```
Code:
```template <class T> bool writeArray(T *array, unsigned long arraySize, std::string fileName)
{
std::ofstream file(fileName.c_str(), std::ios::binary);
if (!file.is_open()) {
std::cerr << "Unable to open \"" << fileName << "\"." << std::endl;
return false;
} else {
std::clog << "\"" << fileName << "\" opened successfully." << std::endl;
std::clog << "Writing " << arraySize *sizeof(T) << " bytes." << std::endl;
file.write((char*)array, arraySize * sizeof(T));
if (file.fail()) {
std::cerr << "Write operation failed." << std::endl;
file.clear();
return false;
} else {
std::clog << "Wrote " << arraySize *sizeof(T) << " bytes." << std::endl;
}
std::clog << "Closing \"" << fileName << "\"." << std::endl;
file.close();
}
return true;
}```

3. I have a couple of questons/observations about the following line of code:
Code:
`board[((14 - (int)(13.8 - ((float)y / 35.217)))*50)+((int)(-25.0 + ((float)x / 34.7)) + 25)] = colorTable(currentColor);`
First how, where is board defined?

Second I would move the calculation from inside the brackets [] to a separate variable, so this variable's value can be tested to insure you do not access the array out of bounds.

Third you can probably remove the C-style float casts from the equation, you already have at least one floating point number in the calculation. I would probably break this calculation up into smaller equations, handling the x and y calculations separately. By breaking the equation up, if you have problems you can display these individual variables to insure that your calculations are correct. It also appears that the -25 and +25 cancel each other out and are not needed.

This is about what I would do for your calculation. I would then test indexValue to insure that it is in bounds for your array. I would also consider changing these "magic" constants to constant variables with meaningful names to help explain what you are trying to accomplish in these calculations.

Code:
```   int yValue = (14.0 - (13.8 - (y / 35.217))) * 50.0;
int xValue = x / 34.7;
int indexValue = yValue + xValue;```
Also is there a reason you are using an array instead of a vector?

Jim

4. Right! Sorry Jim, the board is an array of structures. Lemme dig it out:
Code:
```struct mrtcolor {
float r;
float g;
float b;
};```
And the array:
Code:
`mrtcolor board[1400];`
But, that aside, your simplification is very nice, and when you advise to get rid of the c-style casts, you mean go with like:
[ reinterpret_cast <new_type> (expression) static_cast <new_type> (expression) const_cast <new_type> (expression) ]

As for vector, I -had- a vector solution, but ran into trouble getting boost libraries to link to my project. Hence no boost::serialization, hence vectors are not so easy to get into binary files. That board[1400] array is saved to a binary file, and reloaded.

Searializing vectors basically... was the stumbling block there.

5. In this case I was saying that you don't need the casts at all. However in C++ programs you should actually use the C++ style casts instead of the C style casts.

Jim

6. Originally Posted by jimblumberg
Code:
`   int yValue = (14.0 - (13.8 - (y / 35.217))) * 50.0;`
(14.0 - 13.8)*50.0 is 1.0 .....

7. Originally Posted by M.Richard Tober
And here's the final, compact, Linus Torvalds would shoot me, over simplification, noob, product:
Linux Torvalds is a neanderthal who wouldn't understand the benefits of simplification if it shot him in the foot.

Code is not oversimplified until it's just plain wrong.