Problem with matrices

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Problem with matrices

Ivaylo Beltchev
Hi

I am trying to create a library for matrix and vector operations. matrix and vector are going to be full userdata.

Vectors are easy. I can define __index to return x, y, or z, and __newindex to set them. Then I can do this:
1) a=vector.x -- get the value of x from the vector
2) vector.x=0 -- modify the vector

The matrices prove to be trickier. I want to be able to do this, like in C:
1) a=matrix.position -- get the value of the position (creates a new vector)
2) a=matrix.position.x -- get the value of x from the position
3) matrix.position.x=0 -- directly set the value inside the matrix

The problem is that (3) is equivalent to this:
3a) a=matrix.position; a.x=0
It will create a copy of the position, and set its x to 0. The actual matrix will not be modified. It would work in C because in C matrix.position is not the value of the position, but a reference to it.

I can change matrix.position to return a reference vector object, and any changes to it could be forwarded to the matrix. But then (1) will not work as intended. (2) will still work either way.

Any suggestions?

Thanks
Ivo

Reply | Threaded
Open this post in threaded view
|

Re: Problem with matrices

Jerome Vuarand
The problem is that your proposition 1 is not following lua table
semantics (that may be considered as a normal semantic since tables
are evrywhere in lua). With the table semantics, matrix.position
returns a reference to the value of the "position" field in the matrix
table, so your proposition 3 would be valid but proposition 1 don't
create a new vector.

To make both work you don't have to return a vector, you can return a
proxy object that acts like a vector but in fact is a reference to the
matrix. It would modify the matrix if you modify it.

2006/5/20, Ivaylo Beltchev <[hidden email]>:

> Hi
>
> I am trying to create a library for matrix and vector operations. matrix and vector are going to be full userdata.
>
> Vectors are easy. I can define __index to return x, y, or z, and __newindex to set them. Then I can do this:
> 1) a=vector.x -- get the value of x from the vector
> 2) vector.x=0 -- modify the vector
>
> The matrices prove to be trickier. I want to be able to do this, like in C:
> 1) a=matrix.position -- get the value of the position (creates a new vector)
> 2) a=matrix.position.x -- get the value of x from the position
> 3) matrix.position.x=0 -- directly set the value inside the matrix
>
> The problem is that (3) is equivalent to this:
> 3a) a=matrix.position; a.x=0
> It will create a copy of the position, and set its x to 0. The actual matrix will not be modified. It would work in C because in C matrix.position is not the value of the position, but a reference to it.
>
> I can change matrix.position to return a reference vector object, and any changes to it could be forwarded to the matrix. But then (1) will not work as intended. (2) will still work either way.
>
> Any suggestions?
>
> Thanks
> Ivo
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Problem with matrices

Ivaylo Beltchev
Yes, I understand that. But the table semantics make little sense for matrices. In fact (3) is the only case where that proxy would be needed. In all other cases having a proxy to a vector inside some matrix instead of a real vector can lead to hard to find bugs.

Ideally (for the current situation, not in general), matrix.position.x=0 should behave as matrix:__newindex("position.x",0) instead of matrix:__index("position"):__newindex("x",0). But that's not how Lua works.

The next best thing would be to have a way to distinguish between "matrix.position.x=0" and "a=matrix.position; a.x=0". But again, there isn't.

The next-next best thing would be if matrix.position returns a const vector. The __newindex of a const vector will assert. Then (3) will assert, (2) will just work, and (1) will work if you don't try to modify the result. If you want to modify the result you should make a copy first - a=vector(matrix.position).

That's probably the way I'm going to go. The disadvantage is that I'm sacrificing some of the functionality. The advantage is that if you try to use the system in a way that's not permitted you'll get an error.

Ivo


----- Original Message -----
From: "Jérôme VUARAND" <[hidden email]>
To: "Lua list" <[hidden email]>
Sent: Saturday, May 20, 2006 10:16 PM
Subject: Re: Problem with matrices


> The problem is that your proposition 1 is not following lua table
> semantics (that may be considered as a normal semantic since tables
> are evrywhere in lua). With the table semantics, matrix.position
> returns a reference to the value of the "position" field in the matrix
> table, so your proposition 3 would be valid but proposition 1 don't
> create a new vector.
>
> To make both work you don't have to return a vector, you can return a
> proxy object that acts like a vector but in fact is a reference to the
> matrix. It would modify the matrix if you modify it.
>
> 2006/5/20, Ivaylo Beltchev <[hidden email]>:
> > Hi
> >
> > I am trying to create a library for matrix and vector operations. matrix and vector are going to be full userdata.
> >
> > Vectors are easy. I can define __index to return x, y, or z, and __newindex to set them. Then I can do this:
> > 1) a=vector.x -- get the value of x from the vector
> > 2) vector.x=0 -- modify the vector
> >
> > The matrices prove to be trickier. I want to be able to do this, like in C:
> > 1) a=matrix.position -- get the value of the position (creates a new vector)
> > 2) a=matrix.position.x -- get the value of x from the position
> > 3) matrix.position.x=0 -- directly set the value inside the matrix
> >
> > The problem is that (3) is equivalent to this:
> > 3a) a=matrix.position; a.x=0
> > It will create a copy of the position, and set its x to 0. The actual matrix will not be modified. It would work in C because in C matrix.position is not the value of the position, but a reference to it.
> >
> > I can change matrix.position to return a reference vector object, and any changes to it could be forwarded to the matrix. But then (1) will not work as intended. (2) will still work either way.
> >
> > Any suggestions?
> >
> > Thanks
> > Ivo
> >
> >
>