Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 10 of 10

Thread: Vector3 Class

  1. #1
    Junior Member
    Join Date
    Aug 2012
    Posts
    8
    My Mood
    Mellow
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default Vector3 Class

    Just switching from C++ to Java. I'm working on a Vector3 class, and eventually want to build a triangle class based off of it. I've been inspired due to the fact that the next 6 semesters I will spend taking math courses. I'm going to post my code just for some tips, pointers, and what have you's.
     
    package VectorMath;
    import java.lang.Math;
    /**
     *
     * @author Jonathan Coleman
     */
    public class Vector3 
    {
        private float[] data = new float[3];
     
        public Vector3(){}
     
        public Vector3(float x, float y, float z){
            data[0] = x;
            data[1] = y;
            data[2] = z;
        }
        public Vector3(Vector3 v){
            data[0] = v.x();
            data[1] = v.y();
            data[2] = v.z();
        }
     
        //Operations
        public void add(Vector3 v){
            data[0] += v.x();
            data[1] += v.y();
            data[2] += v.z();
        }
        public void subtract(Vector3 v){
            data[0] -= v.x();
            data[1] -= v.y();
            data[2] -= v.z();
        }
        public void multiplyScalar(float scalar){
            data[0] *= scalar;
            data[1] *= scalar;
            data[2] *= scalar;
        }
        public void divideScalar(float scalar){
            data[0] /= scalar;
            data[1] /= scalar;
            data[2] /= scalar;
        }
        public Vector3 normalize(){
            float length;
            length = (float) Math.sqrt((data[0]*data[0]) +
            (data[1]*data[1]) + (data[2]*data[2]));
            Vector3 normalized = new Vector3(x()/length, y()/length, z()/length);
            return normalized;
        }
        //getters
        public float x()
        {
            return data[0];
        }
        public float y()
        {
            return data[1];
        }
        public float z()
        {
            return data[2];
        }
    }

    Does it appear that I'm doing this right so far? One thing I was confused about was that when I had the array data as data[2] I got an out of bounds exception for using data[2]. Not sure why. I'm still new to programming in general.

    Are there more efficient ways of doing what I'm doing? I know it was real convenient in C++ to overload the operators, but I suppose what we have here is a bit more readable.

    Also, should I make a getLength function? Is the length of a vector used for other calculations other than normalization?


  2. #2
    Junior Member
    Join Date
    Aug 2012
    Posts
    8
    My Mood
    Mellow
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default Re: Vector3 Class

    After reading some other examples, I learned that I could do this:
    public Vector3 add(Vector3 v){
            return new Vector3(x()+v.x(), y()+v.y(), z()+v.z());
        }

    I didn't know that I could do this, coming from C++ I remember that if I used the new keyword I had to delete somewhere else, otherwise memory leaks occur. How does the new keyword differ in java from C++?

  3. #3
    Super Moderator pbrockway2's Avatar
    Join Date
    Jan 2012
    Posts
    939
    Thanks
    6
    Thanked 202 Times in 178 Posts

    Default Re: Vector3 Class

    When you declare "float[] data = new float[3];" the 3 is the number of elements in the data array.

    If you were to use 2 instead of 3 then the runtime would complain about data[2]. That's because data[2] is the third element of the array. The first two are data[0] and data[1].

    -----

    "length" is handy for more than just normalising. For example if you have two vectors representing the positions of two points then the length of the difference between the vectors is the distance between the points.

    More generally, you might find a dot product method handy. The "length" of a vector is just the square root of the dot product of a vector with itself.

  4. The Following User Says Thank You to pbrockway2 For This Useful Post:

    jwcoleman (August 17th, 2012)

  5. #4
    Junior Member
    Join Date
    Aug 2012
    Posts
    8
    My Mood
    Mellow
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default Re: Vector3 Class

    This differs from C++ , thank you for your input.

    In C++ I would declare it as data[2] knowing 0 counted as the first element. At least I'm pretty sure about this.

    Also, I didn't realize that I was doing a dot product within my normalize method.
    Last edited by jwcoleman; August 17th, 2012 at 11:52 PM.

  6. #5
    Super Moderator pbrockway2's Avatar
    Join Date
    Jan 2012
    Posts
    939
    Thanks
    6
    Thanked 202 Times in 178 Posts

    Default Re: Vector3 Class

    Personally I prefer the second of your add() methods.

    In Java you can create a new vector and, once there are no more references to it, it will softly and suddenly vanish away. You don't have to worry about this (no need to write or call a dispose method etc).

    The reason I prefer the second add() is that is doesn't alter the values in the data array. If you do the same with the other methods (have them return a new vector, rather than alter the existing one) you will end up with a so-called immutable object: an object whose state never changes. Like a String, or an Integer, and rather like primitive values.

    Immutable objects are not always what is called for, but they are easy to think and reason about.

    (You can google for more on garbage collection and mutability if it matters)

  7. #6
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Vector3 Class

    A few helpful pointers:

    1. Unless you have a reason to specifically use floats, I would recommend you use doubles.
    2. Depending on what kind of math you're doing I would recommend extending or creating a new class which represents an arbitrary length vector. Note that Java already has a Vector class for a different purpose so you should name it something different (like MVector or MathVector).
    3. I would recommend adding the dot product and cross product operations.
    4. Add some documentation. For the most part this code is fairly self-explanatory, but I would still recommend getting into the habit of effectively documenting your code, especially methods and classes.
    5. Creating an array new float[2] ends up with an array with 2 elements. In Java (and C++), arrays are indexed starting at 0. So the first element is data[0], and the second element is data[1]. data[2] would be the third element, but you never created a third element so it doesn't exist. Java is nice in that it will complain to you about this. C++ will not, and will allow you to modify invalid memory to your hearts content (well, almost).
    6. Unfortunately, there's no way to get around using methods to add/subtract/etc. objects. This is a big limitation in Java which I'm not particularly fond of.
    7. A getLength function might be useful if you intend to create an arbitrary length vector. Otherwise, the length is always going to be 3.

    For heavier math I would recommend using existing software instead of trying to roll you own solution. This doesn't mean that you shouldn't continue implementing math functions in Java, C++, or any other language, rather I'm just making you aware of what's already available. I use a combination of both. A quick list of useful tools:
    • Matlab. One of my all-time favorite scientific/mathematical pieces of software. It's not cheap, though they do offer a student version for ~100 USD. Your school may even provide it to you for free.
    • Octave. The open-source alternative to Matlab. I actually use this on my personal computer because I'm cheap There is recent development into a GUI for Octave, but in my opinion it's most usable as a command-line program.
    • NumPy/SciPy. Open-source projects which add extra mathematical capabilities to Python, a scripting language. I've had limited experience with these, I prefer Octave (mostly because of its compatibility with Matlab, though).
    • Wolfram Alpha. Based off of the Mathematica tool, this is a free online gem of a tool. It can solve equations, create plots, and do fun conversions like calculating Santa's caloric intake on Christmas Eve. There's an option to pay for a premium service but it's still very usable in its free form.
    • Mathematica. This actually isn't a piece of software I've used personally however I have heard wonders about what it can do. It's similar to Wolfram Alpha but much more powerful.
    • Maple. CAS (Computer Algebra System) based program. You can input equations and have them look like how you would write them. However, I'm not particularly fond of Maple. From what I've heard it's most comparable to Mathematica, but Mathematica is much more powerful.

  8. #7
    Junior Member
    Join Date
    Aug 2012
    Posts
    8
    My Mood
    Mellow
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default

    Many vector calculations require this immutable approach. One issue I foresee though is with the translation of vectors. When a 3d object moves through 3d space it's data elements become mutable, requiring a += operation. For instance, adding a velocity vector to a group of vectors, say a triangle, requires you to manipulate that triangle, thus preventing it from being purely immutable.

  9. #8
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Vector3 Class

    Darn, beat to the punch.

    Maybe this time I'll be first

    You can have an add and an addAssign method to provide two different interfaces for your class. This is somewhat similar to the distinction between the + and += operators.

  10. #9
    Junior Member
    Join Date
    Aug 2012
    Posts
    8
    My Mood
    Mellow
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default

    I want to read more about dot and cross products, as a programmer I understand that I must use them for important calculations, but from a mathematical concept I don't fully understand their implications. I thought about doubles, but my purpose is for 3d. I see many applications of vectors for 3d using floats, maybe the amount of data in a double is unnecessary? Also, one of the main reasons I am doing this is for refreshing my programming skills and to prepare the way for opengl programming. Thank you for your suggestions.

  11. #10
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Vector3 Class

    Just so long as you're aware of the implications between floats and doubles. For most graphics-related code the amount of precision difference between floats and doubles is insignificant, and doubles are twice the size. However, that being stated a double is 8 bytes, and 10 MB can hold over 1 million doubles.

    The one area where the difference between floats and doubles will be most apparent is when you mix large quantities and small quantities.

    For example (I wouldn't recommend running this):

    		float f;
    		double d;
    		for (f = 0; f != f + 1.0f; f += 1.0f)
    		{
    		}
    		System.out.println(f);
    		for (d = 0; d != d + 1.0; d += 1.0)
    		{
    		}
    		System.out.println(d);

    If f and d had infinite precision the loops would never end(because x should never equal x + 1).

    However, The loops do end. The first loop ends when f ~= 1.6777216E7, and I'm still waiting for the second loop to end (I suppose I could calculate it that d would have to be >= ~4.5E15).

    Graphics libraries tend to use floats for a few different reasons:
    1. Memory. Often times the amount of points/data is massive and floats are half the size. In addition to memory size, there's memory bandwidth. It will take longer to manipulate the larger memory blocks.
    2. GPU limitations. Many GPU's don't support double precision math (I think this is slowly changing, but many GPU's still don't support doubles).
    3. "Precedence". Basically the same reason you gave (you've noticed everyone else is doing it). Not completely invalid, precedence is a powerful tool because it keeps us from re-inventing the wheel each time. However, it is definitely worth it to occasionally understand and re-validate if other reasons for the precedence are still valid. And you're right about doubles usually being unnecessary for graphics.

Similar Threads

  1. create a test class (main method) to start(run) the class in Java
    By curious725 in forum Java Theory & Questions
    Replies: 5
    Last Post: August 1st, 2012, 03:21 AM
  2. Replies: 3
    Last Post: June 17th, 2012, 06:22 PM
  3. Replies: 7
    Last Post: July 21st, 2011, 02:29 PM
  4. Replies: 3
    Last Post: April 13th, 2011, 03:30 PM
  5. Help requested - testing a class with a tester class, no methods allowed.
    By miketeezie in forum What's Wrong With My Code?
    Replies: 3
    Last Post: February 21st, 2011, 09:40 PM