Need VBase3 operator* (const VBase3& scalar)

Hello

To do vector operation I need to implement

VBase3 operator* (const VBase3& v2)

return VBase3(this->xv2.x,this->yv2.y,this->z*v2.z)

Or there is an equivalent ?

I don’t understand. What kind of vector operation are you trying to do? It looks like you’re doing componentwise multiplication, but what do you need it for?

Hmm… I guess it may be useful to scale multicomponent values, like in color multiplication.

You can always do it componentwise if you need that operation. Or write your own function. But there’s nothing built into Panda to do that particular operation.

David

here my math module, i hope that helps:

'''
Created on 27.04.2011

@author: dirk hochegger
'''
from pandac.PandaModules import Vec3,Point3
import math
class math3D():
    def __init__(self):
        math = "math modul loaded"
    def angelX(self,p0,p1):
        height = p0[0]-p1[0]
        distance = (p0-p1).length()
        alpha = math.degrees(math.sin(height/distance))
        return alpha
    def angelY(self,p0,p1):
        height = p0[1]-p1[1]
        distance = (p0-p1).length()
        alpha = math.degrees(math.sin(height/distance))
        return alpha
    def angelZ(self,p0,p1):
        height = p0[2]-p1[2]
        distance = (p0-p1).length()
        alpha = math.degrees(math.sin(height/distance))
        return alpha
    def VEC(self,p0,p1):
        result = Vec3(p1[0]-p0[0],p1[1]-p0[1],p1[2]-p0[2])
        return result
    def vecLENGTH(self,v):
        result = math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2])
        return result
    def dot(self,v0,v1):
        result = v0[0]*v1[0]+v0[1]*v1[1]+v0[2]*v1[2]
        return result
    def cross(self,v0,v1):  
        result = Vec3(v0[1]*v1[2] - v0[2]*v1[1],v0[2]*v1[0] - v0[0]*v1[2],v0[0]*v1[1] - v0[1]*v1[0])
        return result
    def clampCOLOR(self,r,g,b):
        if r != 0.0 and g != 0.0 and b != 0.0:
            r=255.0/r
            g=255.0/g
            b=255.0/b
            r = 1.0/r
            g = 1.0/g
            b = 1.0/b
        return r,g,b
    def inPERCENT(self,count,id):
        result = 100.0/count*id
        return result
    def normale(self,x,y,z):
        normale = Vec3(2*x-1, 2*y-1, 2*z-1).normalize()
        return normale
    def distanceTO(self,p0,p1):
        return math.sqrt(((p0[0]-p1[0])*(p0[0]-p1[0]))+((p0[1]-p1[1])*(p0[1]-p1[1]))+((p0[2]-p1[2])*(p0[2]-p1[2]))

For the record, Panda3D provides most of the functionality of that class in the Vec3 and Point3 classes. It is probably more efficient and easier to let Panda3D handle the math.

Yes this is for that goal. Need to scale differently by x,y and z axis.

To replace it I must write something like this each time and this is painfull :

Vec3(v[0]*f[0],v[1]*f[1],v[2]*f[2])

This is also use full for velocity too. If you want to extract only the x and z axis :
velocity*Vec3(1,0,1)

or reverse z

velocity*Vec3(1,1,-1)

etc…

It is not obvious that v1*v2 means a componentwise multiplication. It could also be a cross product, or a dot product. These are used much more often, too, so having the multiplication operator do a componentwise multiplication would not only be ambiguous but also counterintuitive.

The examples you used can also be written in a cleaner fashion:

Vec3(v.x * f.x, v.y * f.y, v.z * f.z)

velocity.xz (or velocity.y = 0)

velocity.z *= -1

Ok, if using the * operator is not clear, maybe if we use a method, like this ?

Vec3 Vec3::cwfactor(const Vec3& vec);

For your samples :
vec3 doesnt have x,y or z attributes

[color=red]AttributeError: ‘libpanda.Vec3’ object has no attribute ‘x’

.getXz() return a vec2 not a vec3

velocity[2] *= -1 is an inplace operation

Are you perhaps using an outdated version of Panda3D? The latest is 1.7.2.

And in any case, why not write your own function to make it clean?

def cwfactor(v, f):
    return Vec3(v[0]*f[0],v[1]*f[1],v[2]*f[2])

There’s no reason you should write a messy expression every time you want to use it. That’s what functions are for. It doesn’t have to be a method.

David

lol I feel fighting just for talking about a possible new feature.

Yes I can write function in python.

How about overloading the ‘*’ operator to accept a vector as argument and use that to multiply componentwise?

Do you mean in this person’s Python application, or are you suggesting a change to Panda? Overloading doesn’t work in Python, at least not in a straightforward way, so it wouldn’t work at the Python level.

And as we’ve already discussed earlier in this thread, it doesn’t seem like a good idea to add this at the C++ level, because there are already two different, and much more common, multiplication operations which are defined for vectors; so it’s not at all obvious what is meant by the syntax v1 * v2. And it would surprise a lot of people if v1 * v2 performed a componentwise multiplication.

David

If you think about it only as vectors then yes, it’s quite confusing. But if you think about it as a way to store stuff like colors or scale then it becomes extremely common. At least from my perspective.

It might be that I’m just doing something wrong, but I find myself typing color * color or scale * scale all the time just to find out it doesn’t work and I need to throw a For at it. Sure, I could write a function but I always forget to do it ;D, that’s a different issue, but you should also consider that vectors, in Panda, are not only used… as vectors.

Sometimes, they’re also used for storing information that doesn’t really need 99% of the typical vector operations, but could benefit largely from simple componentwise multiplication.

Another way of solving this issue would be writing a special class for storing stuff like colors or scale. It would definitely save us from all the confusion. In fact, I think it might not be such a bad idea. For instance, a class for color could be capable of taking in hex notation or (0-255, 0-255, 0-255) format.

For the record, there are three different vector classes in Panda. They each store three numbers; but the difference is in the semantic meaning.

Vec3 is a vector, in the mathematical sense (a direction and magnitude).
Point3 is a point in space.
VBase3 is any three numbers without a specific meaning.

So the idea is you should use VBase3 to store your colors, and Vec3 to store things that are actually vectors. The methods like Mat3.mult() are overloaded based on the vector type: a vector times a matrix is a different operation than a point times a matrix.

But still, I don’t think defining even VBase3 * VBase3 as a componentwise multiplication is a good idea, because the potential for confusion is too great. But how about we add a new VBase3.componentMult() method, in conjunction with VBase3.dot() and VBase3.cross()?

David

Good to know :wink:. I knew the difference between Vec3 and Point3, which is quite obvious, but I never knew what was the purpose of VBase3. I thought it was just there because stuff inherits from it (hence the “base” name).

I’m personally all for it. Especially since I don’t find myself doing this operation on more than two vectors at once, so a method would be a nice solution.

I would say that it needs a shorter name, but I can’t think of a better one :wink:.

+1

mulComp ?

I’m not a big fan of abbreviated names–I don’t like to sacrifice clarity for typing speed (usually it’s the lack of the former that slows development, not the latter).

But I also appreciate conciseness, so if anyone has a suggestion for a shorter name that obviously has the same meaning without simply abbreviating, I’m all for it.

David

Yeah, I meant the C++ side. I looked up the API and it only mentions multiplication with scalars (floats).
Strange, that other overloaded operators are listed and the multiplication isn’t.

I think this operation -i mean componentwise multiplication- might become expensive on the python side and it might be useful in cases mentioned by others above.

So first, what do you think about adding a method which implements this, David?
And if the only open question is how to name it, how about scale() or setScale()?