vec2 * vec2 should be implemented!

Just wanted to state that vec2 * vec2 should be implemented the same way as vec2 + vec2.

print( vec2(2,2) + vec2(2,2) ) --prints [4,4]
print( vec2(2,2) * vec2(2,2) ) --FAILS!

--work around:
local v1 = vec2(2,2)
local v2 = vec2(2,2)
local v3 = vec2( v1.x*v2.x, v1.y*v2.y )
print(v3) --prints (4,4)


A bold statement!

Currently vec2 supports the use of the * for multiplication by a scalar. You can also do dot product and cross product multiplication of vectors.

I think you are after an element by element multiplication

somehow this is misleading. naturally I would think, *, is multiplying, and expect it to return an element by element multiplication result, IF two vec2 are compared. The current behaviour is ok when passing only a number as the multiplier.

I didn’t implement an element-wise multiplication because I felt it was a bit ambiguous. Many programming libraries overload vector * to mean cross product or sometimes even dot product.

I tried to be a bit conservative with the meaning of operators as they relate to vectors in Codea. I felt that unary negation, element-wise addition and subtraction, and scalar multiplication and division were appropriate as they were the common uses.

thank you for your point of view. but it would be helpful to have at least something like vec2:multiply(vec2). its anyway shorter than manually implemented solutions.
just my opinion. sorry for any inconvenience


local mt = getmetatable(vec2())
mt["multiply"] = function(self,v)
  return vec2(self.x*v.x,self.y*v.y)

@Andrew_Stacey Yes, but what is the getmetatable() for? Couldn’t you just:

(also untested)

vec2["multiply"] = function(self, v)
  return vec2(self.x * v.x, self.y * v.y)

Since vec2 is a global variable/class, you can simply add a method… or am I wrong?

Simple way to test!

You need the metatable because vec2 is a userdata so you can’t arbitrarily add functions to it.

Should element-wise multiplication be implemented via the * operator? What do you all think? Is this a good idea?

i would find that confusing…

Me too, but @se24vad suggestion of something like vec2: multiply(vec2) is a good one

thank you for the wisdom @Andrew_Stacey and thanks to all for the active discussion! vec:multiply would be enough @Simeon. Thanks for all the ideas and code and open ears for my issue)

Only if it doesn’t slow down the more usual use of *. I guess the dispatch to check type might steal some cycles? Better use Staceys addition if needed. Add bit operators instead :slight_smile:

But I would like a matrix * vec3 and matrix * vec4.

@tnlogy Given that matrix is 4x4, matrix * vec3 doesn’t make sense.

What would be nice would be easy conversion between the vector types, somewhat like in shaders. So I could do v = vec3(1,2,3) u = vec4(v,1).

It could convert to vec4 and back again behind the scenes, so that I can use matrix:rotate and such conveniently. :slight_smile:

But you’d want different conversions depending on whether you were doing points or normals. For points, you’d want to promote a vec3 with 1 in the last place, for normals then 0. So m * vec4(v,1) allows you to specify the promotion explicitly without over complicating matters.

Yes, that sounds good