Skip to main content
GameDev.net gamedev.net
🔒 Locked 🤖 Godot

Point / Vector understanding

Started by BierbyteZ Mar 25, 2011 at 1:36 PM 23 replies 4.6k views
Original Post
BierbyteZ
BierbyteZ
Hey Everyone,

Ive got a question for Maths again X.x since I've found a nice tutorial on Vector Maths and somehow Im a bit confused about the definition of a Point and a Vector.

So a Pioint is just a location in space
A Vector has a direction and length but has no location at all.

I wonder why for example XNA/C# is using the Vector2 Struct for storing object coordinates when Vectors arent supposed to have a location?
Is it because the Vector stores the disctance between the screen Origin and the object position?

This would change my view on graphics alot
[size="2"]Java / C# Developer
Volgogradetzzz
Volgogradetzzz
Yes, you right, Vectors arent supposed to have a location, but they can describe displacement from one point to another. So describing bodies position with vector is the same as saying 'this body is [x; y] far from origin'.
Zlodo
Zlodo
I wonder why for example XNA/C# is using the Vector2 Struct for storing object coordinates when Vectors arent supposed to have a location?
Is it because the Vector stores the disctance between the screen Origin and the object position?

Yes, this is the reason. Vector and points are similar because the later is a special case of the former:

A vector represents a displacement in space.
A point is typically represented as a displacement from the origin to the position of that particular point, so it is a vector too.
alvaro
alvaro
Let me try to describe the situation emphasizing which operations we use on points and vectors.


A point is just a location in space, as you said. Vectors can represent several things, but in this context they represent translations. The basic operation that gives the whole thing structure is the addition of a point and a vector (i.e., translating the point by the vector, and getting another point as a result).

If you pick a point as the origin, you get a one-to-one matching of vectors and points: Associate to each vector the point that you get when you add it to the origin. This is what allows you to use Vector2 to represent points. But remember that there was an arbitrary choice of origin that needed to happen to make this work.

The reason why I usually implement separate classes is that the allowed operations on points and vectors are different. For instance, you can add a point and a vector, and the result is a point, as we said earlier. But adding two points together makes no sense. You could go ahead and add up their coordinates, but the result depends on your choice of origin, so this operation is an artifact of how you chose to label the points with numbers, and has nothing to do with the points themselves. Similarly, multiplying a vector and a number yields a vector, but multiplying a point and a number doesn't mean anything.

These are the operations that do make sense:
Vector + Vector = Vector
Vector - Vector = Vector
Vector * Number = Vector
Point + Vector = Point
Point - Point = Vector
w1 * Point1 + w2 * Point2 + ... + wn*Pointn = Point, where w1+w2+...+wn = 1 (computing a barycenter)

At some point you'll encounter matrices (3x3 matrices if you are working in 2D, or 4x4 if you are working in 3D) that represent affine transformations (translations, rotations, shearings, scalings, and combinations of these). In order to apply them to a point, you'll need to add an extra coordinate "1". In order to apply them to a vector, you'll need to add an extra coordinate "0" instead.

Those are really all the operations I can think of.

Buckeye
Buckeye
A Vector has a direction and length but has no location at all ... using the Vector2 Struct for storing object coordinates when Vectors arent supposed to have a location[/quote]
Not necessarily. The definition you mention is just one of several definitions. As a general definition, a "vector" is an ordered set of components. Given that definition, a Vector2 (which has float-type components) can be used for any mathematical operation that needs 2 float components in a known order, and storing coordinates in X,Y order is a perfectly valid use. It's also valid to used a Vector2 as a direction with magnitude. It's also commonly done to use a Vector2 to store texture coordinates, which describe a "location" in an image or texture.

In fact, interpreting a vector structure as a point in space, a direction with a magnitude, or as a location within an image/texture depends only on the use to which you want to put the vector.

E.g., the Standard Template Library (C++) defines a std::vector. A std::vector can be used to store components of any type (floats, integers, complex structures) in a fixed order. A std::vector has many functions and overloaded operators, none of which has anything to do with specifically interpreting a "vector" as related to graphics, 2D space or 3D space. That is also consistent with the general definition of vector.
Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly. You don't forget how to play when you grow old; you grow old when you forget how to play.
alvaro
alvaro

A Vector has a direction and length but has no location at all ... using the Vector2 Struct for storing object coordinates when Vectors arent supposed to have a location

Not necessarily. The definition you mention is just one of several definitions. As a general definition, a "vector" is an ordered set of components. Given that definition, a Vector2 (which has float-type components) can be used for any mathematical operation that needs 2 float components in a known order, and storing coordinates in X,Y order is a perfectly valid use. It's also valid to used a Vector2 as a direction with magnitude. It's also commonly done to use a Vector2 to store texture coordinates, which describe a "location" in an image or texture.[/quote]

I can't agree with almost any of that. "Vectors" are elements of a "vector space". A vector space is a set whose elements can be added together, subtracted and scaleds (i.e., multiplied by numbers), as long as these operations satisfy a few basic identities. See this Wikipedia page for details.

An important example of vector space is R^n, which is the set of ordered n-tuples of real numbers, with component-by-component addition and subtraction, and where scaling is done by multiplying each coordinate by the scale. You can replace real numbers with any other field (fields are sets whose elements can be added, subtracted, multiplied and divided).

It is definitely not the case that any object that is described by two ordered real numbers is a vector. A point on a map of Earth is described by latitude and longitude, but it's not a vector (what's New York + London?). A point on the plane is not a vector, as I discussed in my previous post. A normal distribution is characterized by its mean and variance, and addition sort of works if you are considering independent variables, but I can't think of a meaningful way to subtract distributions in a way that would make the vector-space structure work out.

E.g., the Standard Template Library (C++) defines a std::vector. A std::vector can be used to store components of any type (floats, integers, complex structures) in a fixed order. That is also consistent with the general definition of vector.[/quote]
std::vector is a very unfortunate name, and I read that Alex Stepanov regrets the name choice, but now it's too late to change it. In the words of Bjarne Stroustrup: "One could argue that valarray should have been called vector because it is a traditional mathematical vector and that vector should have been called array. However, this is not the way the terminology evolved." I actually think that the new std::array in C++0x should have been called vector, std::vector should have been called array and nobody cares what std::valarray is called, because it's not all that useful.
h4tt3n
h4tt3n
Buckeye, Alvaro

I think you are talking about different things, hence the disagreement. Buckeye is talking about the multitude of uses to which a vector class can be put in practical programming, and Alvaro is talking about the strict mathematical definition of the term "vector".

Cheers,
Mike
Buckeye
Buckeye
@h4tt3n: Actually, you have it backwards. I referred to one of the most general mathematical definitions of vector. Using that definition (an ordered set of components) explains and supports the way various classes and their functions/overloads are defined in many APIs, and, more importantly, the way vectors are used by many programmers - i.e., not just a set of numbers specifying a magnitude and direction.

I would disagree that "something with magnitude and direction" is the strict mathematical definition of the term "vector." It is, rather, a definition assumed and used contextually in relation to other math concepts, as alvaro mentions, such as vector spaces, etc.

However, if one thinks of vectors as "an ordered set of components," it is easier to accept and understand the way various "things" named vector are defined and used.
Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly. You don't forget how to play when you grow old; you grow old when you forget how to play.
alvaro
alvaro
Buckeye is right in that vectors are a significantly more general notion than just "magnitude and direction" (or "little arrows", as I like to call them). They are even more general than what Buckeye describes. For instance, continuous functions from [0,1] into R form a perfectly good vector space, although its dimension is a large infinity, so you can't just think of them as a list of numbers.


However, this thread is about the difference between points and vectors, and points are not vectors. See the Wikipedia page on affine geometry.

Using a vector class to represent points is something that some programmers find convenient, but it underutilizes the power of the type system.
Helicobster
Helicobster

Using a vector class to represent points is something that some programmers find convenient, but it underutilizes the power of the type system.


Yes, by distinguishing between points and vectors you can add all sorts of useful limitations to your program, and at the same time, remove a great deal of unwanted simplicity.

I don't think I've ever seen anyone claim there's a useful distinction between points and vectors before. I don't think I've ever seen an API that made that distinction, either. It seems completely unnecessary, like making a distinction between 'real numbers' and 'scalars' and putting special conditions on how they interact.

Surely if you're coding it right, your point class should end up identical to your vector class anyway, because there's no reason to disallow vector operations on points or vice versa. So why not just implement a combined vector/point class and flip a coin when it comes time to name it? What is the actual benefit (practical or philosophical - I'm just not seeing it) of treating points and vectors as different kinds of data?
SriLumpa
SriLumpa

What is the actual benefit (practical or philosophical - I'm just not seeing it) of treating points and vectors as different kinds of data?


I would say type safety. Note that I'm OK with confusing points and vectors, but I understand the point in separating. A point is the position of something, for example, and adding 2 points has no meaning.
nhold
nhold

[quote name='Helicobster' timestamp='1301635465' post='4792887']
What is the actual benefit (practical or philosophical - I'm just not seeing it) of treating points and vectors as different kinds of data?


I would say type safety. Note that I'm OK with confusing points and vectors, but I understand the point in separating. A point is the position of something, for example, and adding 2 points has no meaning.
[/quote]


Unless you want it to.

I agree with Helicobster. Type safety? Of what? They are both essentially numbers in some sort of order which only vary in size (xy, xyz). Everything you use a point for you can use a vector for because they are both just two numbers. I don't understand how you guys are saying points that represent a position is different to a vector that represents a translation because they both have an origin that they 'translate' from e.g. You can say GuyA is positioned at point 2,2 however this means nothing unless you have an origin (Top Left of the screen), the same can be said for GuyB positioned at the vector 2,2.

@alvaro

"but the result depends on your choice of origin"

That statement can be said of vectors.
Engineering Manager at Deloitte Australia
Zakwayda
Zakwayda
It may be that these operations would be characterized in a different way from a purely mathematical perspective, but it seems to me that the need for 'point addition' does sometimes arise in practice. A simple example would be finding the average of a set of points. Perhaps there's a different way to express the problem, but a typical implementation of a function that returns the average of a set of points will simply add the points together and divide by the total.

I'm not making any claims regarding the mathematical correctness of this (or lack thereof), but like the above poster, I've rarely if ever seen separate point and vector classes used in production code or in commonly used math libraries. Of course having separate classes is a viable option and may be preferred by some, but I don't think it's very common to do it that way (and I've never felt a need for it myself).
haegarr
haegarr
Mathematically I'm using the term "vector" also as an ordered set of co-efficients in a space. I further distinguish between position vectors (or points if you want) and direction vectors, obeying the rules alvaro has stated somewhere above. The distinction comes into play when transforming the vectors: Direction vectors don't know of locations in space and hence are invariant to translation, while position vectors are variant to translation. When using homogeneous co-ordinates this is expressed by using 0 (for direction vectors) or non 0 (for position vectors), handling the translational difference is automated. They must be distinguished further when using normals and positions in a space that becomes scaled, especially if the scale is non-uniformly. So yes, one has to take care of what a vector means.

I had a math library that distinguished type-wise between directions and points in the early days, just for the case of safety (although it lacked the same safety for normals or unit vectors in general). However, sometime it became not only inconvenient (e.g. some use cases needed to subtract the point 0 from the point of interest just to yield in a direction vector) but also spurious (there was a mismatch with transformations; I don't remember the details anymore). Nowadays I deal with a single vector class only and have different routines where positions and directions must be distinguished "manually", and simply make sure to pick the correct routines for the intention.
alvaro
alvaro

I agree with Helicobster. Type safety? Of what? They are both essentially numbers in some sort of order which only vary in size (xy, xyz). Everything you use a point for you can use a vector for because they are both just two numbers.

I can measure the angle between two vectors, but not between two points. I can measure the length of a vector, but there's no such thing as the length of a point. You can normalize a vector, but not a point. You can scale a vector by 10, but not a point. Those should be enough examples.

I don't understand how you guys are saying points that represent a position is different to a vector that represents a translation because they both have an origin that they 'translate' from e.g. You can say GuyA is positioned at point 2,2 however this means nothing unless you have an origin (Top Left of the screen), the same can be said for GuyB positioned at the vector 2,2.[/quote]
You just gave two examples of points: Although you used the word "vector" in the latter example, you are using the vector only to describe a position, by adding it to an origin.

If instead you talk about the vector (2,2), which means "translate 2 units to the right and 2 upwards", which is a proper vector, you don't need to pick an origin at all for this to make sense. You can add that vector and (-2,0), which means "translate 2 units to the left", with the result being (0,2), which means "move 2 units upwards". This operation wouldn't make sense with points, and if you did it anyway you would get a different result if you were to change the arbitrary choice of origin.

@alvaro

"but the result depends on your choice of origin"

That statement can be said of vectors.[/quote]

No. You really aren't getting it. I don't know how else to explain it. Although appeals to authority shouldn't play a role in Math, let me tell you that I used to do research in Geometry for a living, and the way I am presenting things is important in certain contexts. You can feel free to ignore this in game programming, and you probably won't run into much trouble (other than having to be very careful as to whether you append a "1" or a "0" at the end of the point or vector when applying an affine transformation in the form of a matrix), but there really is a difference.
Zakwayda
Zakwayda
@alvaro: To be clear, I'm not really trying to argue against your points here; I'm just discussing. And, I certainly strive for correctness of terminology, and agree that it's important in general. To address a couple of points though:

You can normalize a vector, but not a point.[/quote]
In code to generate a sphere mesh procedurally, you might write something like the following:

vertex.normal = normalize(vertex.position);
Strictly speaking, it's probably more correct to write:

vertex.normal = normalize(vertex.position - origin);
However, I think most game developers would be more likely to write the former than the latter, with the understanding that the vertex position is interpreted (implicitly) as a vector relative to the origin.

there's no such thing as the length of a point.[/quote]
The above code would also of course require taking the 'length' of the vertex position (again, we could say that the position is being interpreted as a vector from the origin in this context).

You can scale a vector by 10, but not a point.[/quote]
Code to apply a uniform scaling to a mesh would most likely look something like this:

foreach (position in positions) {
position *= scale;
}

While your statements may all be true, I'd say that most of the things you're saying can't be done with points are in fact frequently done in practice, in the context of game development at least. I'm certainly not for continuing to do things wrong simply due to inertia, but it seems to me that for most game programmers, there's an understanding that in some cases a point will be interpreted as a vector from the origin, and/or that an implicit '- origin' can be assumed.

To do it 'correctly', it seems the scaling code would have to look something like this:

for each (position in positions) {
position = origin + (position - origin) * scale;
}

But I think it's pretty unlikely that you'd see it done that way in practice.

Again, I'm not for doing things wrong just because it's convenient. But, I'm not entirely convinced that these sorts of shortcuts are necessarily incorrect. (Or, at the very least, I'd argue that the typical approach of using a single class to represent both points and vectors is justifiable in the context of game development.)
alvaro
alvaro
@jyk: I think we basically agree.
Helicobster
Helicobster

I can measure the angle between two vectors, but not between two points. I can measure the length of a vector, but there's no such thing as the length of a point. You can normalize a vector, but not a point. You can scale a vector by 10, but not a point. Those should be enough examples.


Your examples are of things you've decided that you're not going to be able to do, because you've decided in advance to make a distinction between points & vectors. Those of us who do not make that semantic distinction do those things all the time, however, without issue. If point==vector, angles & lengths & scales all become meaningful & obvious automatically. Any possible ambiguities are resolved by the contexts in which they're used.

For example if you're trying to scale a point by 10 because you're scaling vertices of a 3D mesh, it makes perfect sense in that context. There's no context in which you'd need to find the angle between just two points, though, so that issue never arises. Well... not for much longer than it takes to realise what you're doing, anyway, and think of a third point to use.


It sounds like your academic background has left you with unnecessary baggage, and now you're using more code to produce less functionality. You may be quite sure you'd be deemed correct in academic circles, but are you sure that the extra complexity is doing you & your code any good?
szecs
szecs
Um, does this difference still hold, if we are talking about 4D space? (homogeneous coordinate representation)
It seems that in this 4D space position and direction are pretty much the same. And the 3D 'vectors' are just projections.

Anyway, practically I consider them different things. When learning about them, referring as "position vector" and "direction vector" helped me a lot.
haegarr
haegarr

Um, does this difference still hold, if we are talking about 4D space? (homogeneous coordinate representation)
It seems that in this 4D space position and direction are pretty much the same. And the 3D 'vectors' are just projections.

Dealing with 3D vectors in a 4D homogeneous space doesn't unburden you from distinguishing between positions and directions. Instead, it gives you an explicit way of doing so. The homogeneous co-ordinate is 0 for direction vectors and non-zero for positions, where 1 is the value especially for "normalized positions" (where dropping the homogeneous co-ordinate yields in the affine counterpart).


Anyway, practically I consider them different things. When learning about them, referring as "position vector" and "direction vector" helped me a lot.

Seconded. Practically they are different things. Whether one considers this by explicit types, spaces, or contexts is mainly a matter of personal taste, because positive arguments can be found for the one as well as for the others.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.