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

  1. #1
    C++ Enthusiast M.Richard Tober's Avatar
    Join Date
    May 2011
    Location
    Georgia
    Posts
    56

    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. #2
    C++ Enthusiast M.Richard Tober's Avatar
    Join Date
    May 2011
    Location
    Georgia
    Posts
    56
    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;
            file.read((char*) array, arraySize * sizeof(T));
            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. #3
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    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. #4
    C++ Enthusiast M.Richard Tober's Avatar
    Join Date
    May 2011
    Location
    Georgia
    Posts
    56
    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) ]
    Your advice prompted me to learn about these, thank you!

    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. #5
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    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. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by jimblumberg View Post
    Code:
       int yValue = (14.0 - (13.8 - (y / 35.217))) * 50.0;
    (14.0 - 13.8)*50.0 is 1.0 .....
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by M.Richard Tober View Post
    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.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C++ math equation
    By XodoX in forum C++ Programming
    Replies: 22
    Last Post: 03-02-2009, 12:02 AM
  2. zero reducing vocals ?
    By geek@02 in forum Tech Board
    Replies: 5
    Last Post: 04-25-2008, 10:50 PM
  3. Converting String to Math Equation
    By draggy in forum C++ Programming
    Replies: 5
    Last Post: 07-10-2005, 06:59 PM
  4. Math Equation Program (I can't find the problem with my program!)
    By masked_blueberr in forum C Programming
    Replies: 14
    Last Post: 07-06-2005, 11:53 AM
  5. A math equation
    By dizolve in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 12-17-2002, 12:56 PM