SFML community forums

Help => System => Topic started by: Weeve on February 17, 2013, 07:00:06 am

Title: No Operand * and Operand / for sf::Vector2*sf::Vector2
Post by: Weeve on February 17, 2013, 07:00:06 am
Sfml 2.0 Release candidate.

irritatingly, there is no * and / operator for two sf::Vector2s.. its easily avoidable by doing a memberwise multiplication myself, just... irritating, if there is a *= and /=, why not have a * and / operator?
Title: Re: No Operand * and Operand / for sf::Vector2*sf::Vector2
Post by: Halsys on February 17, 2013, 07:13:40 am
Um I'm pretty sure you CAN do that, Says in the in the documentation anyway.
http://www.sfml-dev.org/documentation/2.0/classsf_1_1Vector2.php#ac7499d842cf153bea0f567b2b57256b5

*Seconds Later*
Ya, No they work... This is odd... Try Doing sf::operator*(AVector,BVector) instead of just *.
Kinda of a horrible little hack yeah, but it works.
Title: Re: No Operand * and Operand / for sf::Vector2*sf::Vector2
Post by: Weeve on February 17, 2013, 07:21:20 am
documentation is for a scalar, what do you mean by 'sf::operator*(AVector,BVector)' is that even valid syntax?
Title: Re: No Operand * and Operand / for sf::Vector2*sf::Vector2
Post by: Halsys on February 17, 2013, 07:53:59 am
Well the function I showed you was the scalar function that Multiplies a SFML Value(Example: sf::vector2f) by a int or float. But looking at this... You could actually make your own function that can do multiplication with 2 sf::vectors. Want me to make one? I'm going to make it for myself anyway.

And little note here... Any none standard math functions can be made..."*" is actually a shorter version of operator*(int,int)...Except the standard library hard coded it so calling it by that wont work...I tried it anyway and that's what I'm guessing.
Title: Re: No Operand * and Operand / for sf::Vector2*sf::Vector2
Post by: Halsys on February 17, 2013, 08:19:29 am
Alright so I made those functions... all you do is drop the functions in to the Vector2.hpp you have and your cool.
////////////////////////////////////////////////////////////
/// \relates Vector2
/// \brief Multiply 2 Vectors
///
/// \param left  Left operand (a vector)
/// \param right Right operand (a vector)
///
/// \return (A Multiplied Vector)
///
////////////////////////////////////////////////////////////
template <typename T>
Vector2<T> operator *(const Vector2<T>& left, const Vector2<T>& right)
{
    T X = left.x * right.x;
    T Y = left.y * right.y;
    return Vector2<T>(X,Y);
}
////////////////////////////////////////////////////////////
/// \relates Vector2
/// \brief Divide 2 Vectors
///
/// \param left  Left operand (a vector)
/// \param right Right operand (a vector)
///
/// \return (A Divided Vector)
///
////////////////////////////////////////////////////////////
template <typename T>
Vector2<T> operator /(const Vector2<T>& left, const Vector2<T>& right)
{
    T X = left.x / right.x;
    T Y = left.y / right.y;
    return Vector2<T>(X,Y);
}
 
Title: AW: No Operand * and Operand / for sf::Vector2*sf::Vector2
Post by: eXpl0it3r on February 17, 2013, 08:39:46 am
It's mostly a mathematical reason. There's no multiplication defined for vectors, or rather there are many different ways multiplication can get interpreted.
You'd now want a component vise multiplication, but why shouldn't it be the dot product? Or which version of the dot product?
Besides that, SFML doesn't try to be a math library. And I think Thor provides at least functions for the dot product.
Title: Re: No Operand * and Operand / for sf::Vector2*sf::Vector2
Post by: Nexus on February 17, 2013, 11:41:08 am
An important rule for operator overloading is: Only do it when the semantics are clear. Multiplication and division of two vectors are not clear, since they are not mathematically defined. As eXpl0it3r mentioned, you can interpret * also as dot or even as cross product.

In Thor, I wrote named functions (http://www.bromeon.ch/libraries/thor/v2.0/doc/_vector_algebra2_d_8hpp.html) for the vector operations:
sf::Vector2f a, b;
sf::Vector2f c = thor::dotProduct(a, b);
sf::Vector3f d = thor::crossProduct(a, b);
sf::Vector2f e = thor::componentwiseProduct(a, b);
sf::Vector2f f = thor::componentwiseQuotient(a, b);

By the way, this reminds me of something I thought about long ago: The renaming of "componentwise" to "cwise"... Otherwise the latter two function calls are really long in expressions.
Title: Re: No Operand * and Operand / for sf::Vector2*sf::Vector2
Post by: Weeve on February 17, 2013, 05:19:35 pm
In all the environments I've used, * has never meant dot, although I know it can, that's the reason to read documentation before using something, operators are supposed to all be member-wise. Dot and cross are rather expensive operations, so I can't imagine anyone using the * operator for them without reading documentation

Also, explain ambiguity in the / operator?

I believe 1.6 used the * operator, and I never had ambiguity problems.

Should I write my own Vector2/3 class inheriting Sfml's Vector2/3s, or is there somewhay I can add just the * operator without a class write?


reason I'm considering it:
sf::Vector2<unsigned int> Resolution = Display._App.getSize();
sf::Vector2<float> ViewResolution = Display._App.getView().getSize();
sf::Vector2<float> ResChange(ViewResolution.x/Resolution.x,ViewResolution.y/Resolution.y);
sf::Vector2<int> MPos = sf::Mouse::getPosition(Display._App);
sf::Vector2<int> RelativeMPos(MPos.x*ResChange.x,MPos.y*ResChange.y);
int Bbi = MainMenu.GetBoundingBoxIndex(RelativeMPos);
Title: Re: No Operand * and Operand / for sf::Vector2*sf::Vector2
Post by: krzat on February 17, 2013, 05:39:39 pm
You may want to use mapPixelToCoords (https://github.com/SFML/SFML/blob/master/include/SFML/Graphics/RenderTarget.hpp#L180).

IMO it would make sense to implement *, / as componentwise. GLSL works like that, and it's fine.
Title: Re: No Operand * and Operand / for sf::Vector2*sf::Vector2
Post by: Laurent on February 17, 2013, 06:18:33 pm
Quote
I believe 1.6 used the * operator
There weren't more operators in SFML 1.6 than in SFML 2.0.

Quote
Should I write my own Vector2/3 class inheriting Sfml's Vector2/3s, or is there somewhay I can add just the * operator without a class write?
Everything's public in sf::Vector, you can just write your operator as a non-member function and that's it.

Quote
reason I'm considering it:
sf::Vector2<unsigned int> Resolution = Display._App.getSize();
sf::Vector2<float> ViewResolution = Display._App.getView().getSize();
sf::Vector2<float> ResChange(ViewResolution.x/Resolution.x,ViewResolution.y/Resolution.y);
Mixing types in operators requires to use promotion rules to deduce the return type (ie, int * float = float, and it's the same with vectors). This can be done quite easily in C++11, but not in C++03 (unless I write every possible combination explicitely). So your use case is good because it demonstrates a new problem that I didn't think about yet ;)
Title: Re: No Operand * and Operand / for sf::Vector2*sf::Vector2
Post by: Nexus on February 17, 2013, 07:13:40 pm
operators are supposed to all be member-wise
Who says that? The multiplication operator for std::complex doesn't work member-wise, for a good reason.

Dot and cross are rather expensive operations, so I can't imagine anyone using the * operator for them without reading documentation
Where is the connection between performance and the need to read the documentation? This doesn't make sense.

Also, explain ambiguity in the / operator?
Google for "vector division" ;)

And / should be consistent with *. Because the division between vectors isn't defined mathematically, I wouldn't define it for vector classes. It helps to avoid potential errors when a scalar division is actually meant. Since the use cases of component-wise multiplication and division are rather rare, I don't consider a named function a real disadvantage.