Code Monkey home page Code Monkey logo

Comments (7)

joshinils avatar joshinils commented on August 19, 2024

of course this also happens with the other types of operators

from olcpixelgameengine.

joshinils avatar joshinils commented on August 19, 2024

oh and the current implementation also means that adding an olc::vi2d to an olc::vd2d is possible and results in an olc::vi2d, but adding an olc::vd2d to an olc::vi2d is not possible, whereas adding an int to a double and ading a double to an intis both possible and both result in a double if i do: auto v = 100 + 3.14 or auto v = 3.14 + 100. It would make sense to add the underlying types and then cast to the template type of one of the two vectors.

from olcpixelgameengine.

OneLoneCoder avatar OneLoneCoder commented on August 19, 2024

Good observations as usual. I'll address in next update.

from olcpixelgameengine.

OneLoneCoder avatar OneLoneCoder commented on August 19, 2024

Hi Josh, Ive been working through this with the imminent release of PGE2, and it works well until you have the scenario olc::vf2d * olc::vi2d.

template<class T, class A> inline v2d_generic<T> operator * (const v2d_generic<T>& lhs, const A& rhs)
{ return v2d_generic<T>((T)(rhs * (A)lhs.x), (T)(rhs * (A)lhs.y)); } // Thanks Joshinils
template<class A, class T> inline v2d_generic<T> operator * (const A& lhs, const v2d_generic<T>& rhs)
{ return v2d_generic<T>((T)(lhs * (A)rhs.x), (T)(lhs * (A)rhs.y)); }

Now I need to handle explicitly vec * vec, because the type A above wont discriminate. That's ok, I'll do this:

template<class T, class A> inline v2d_generic<T> operator * (const v2d_generic<T>& lhs, const v2d_generic<A>& rhs)
{ return v2d_generic<?>((?)(rhs.x * (?)lhs.x), (?)(rhs.y * (?)lhs.y)); }

But now I have an issue regarding which combination is correct? If both vecs are same type, no problem, but if they aren't which is right?

olc::vi2d b = { 3, 3 };
olc::vf2d c = { 0.5f, 0.5f };
olc::vf2d d = b * c; // d = {1.0, 1.0}
olc::vf2d e = c * b; // e = {1.5, 1.5}

from olcpixelgameengine.

joshinils avatar joshinils commented on August 19, 2024

I'm not exactly sure what multiplication you want to implement.
The dot product of two vectors results in a scalar, not a vector, the cross product is only defined for vectors of length 3.

Since this is what the underlying integral types do:

int   b = 3;
float c = 0.5f;
float d = b * c; // d == 1.5
float e = c * b; // e == 1.5

It could be wise to mimic the same behaviour. Either through template specialization or use of enable_if, but I don't think I'm qualified to aswer how.
You could also only allow the type of A to be an integral type, so you would ban v2d from being a valid template argument for scalar multiplication with A.

As a mathematics student I'd argue neither are correct and the compiler should not let olc::vf2d d = b * c; compile, however float f = b * c; is fine and f should equal 3.

Could this work:?

template<class T> inline T operator * (const v2d_generic<T>& lhs, const v2d_generic<T>& rhs)
{ return lhs.x * rhs.x + lhs.y * rhs.y; }

Then the multiplication should be done on the integral type and work like what I first mentioned, right? Does a copy constructor for v2d exist? Can this be used to implicitly convert a vi2d to a vf2d and vice versa?

from olcpixelgameengine.

OneLoneCoder avatar OneLoneCoder commented on August 19, 2024

It would be an element wise operation, which is quite customary though I appreciate the syntax makes it look like a cross product

from olcpixelgameengine.

MyGoodSir avatar MyGoodSir commented on August 19, 2024

the type_traits library can help with this

#include<type_traits>
template<class T, class A>
inline v2d_generic<typename std::common_type<T,A>::type>  operator *  (const v2d_generic<T>& lhs, const v2d_generic<A>& rhs) 
{ return v2d_generic<typename std::common_type<T,A>::type>(lhs.x * rhs.x, lhs.y * rhs.y); }

that makes this:

int main(){
	vd2d dvec(1.5, 1.5);
	vi2d ivec(2, 2);

	auto di_vec = dvec * ivec;
	auto id_vec = ivec * dvec;

	std::cout << "d * i: "<< di_vec << "\ni * d: " << id_vec;
}

output this:

d * i: (3.000000,3.000000)
i * d: (3.000000,3.000000)

from olcpixelgameengine.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.