Skip to content

Add adding and subtraction operations between a number and a quaternion;#18911

Merged
opencv-pushbot merged 1 commit intoopencv:masterfrom
chargerKong:quat
Dec 2, 2020
Merged

Add adding and subtraction operations between a number and a quaternion;#18911
opencv-pushbot merged 1 commit intoopencv:masterfrom
chargerKong:quat

Conversation

@chargerKong
Copy link
Copy Markdown
Contributor

@chargerKong chargerKong commented Nov 24, 2020

I found that many papers directly write a number plus a quaternion.
It has to write like this

double number = 2.0;
Quatd q{1, 2, 3, 4};
Quatd ans = Quatd(number,0,0,0) + q;

which is too much trouble for users. So adding this operations may be friendly and convenience

Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

  • I agree to contribute to the project under Apache 2 License.
  • To the best of my knowledge, the proposed patch is not based on a code under GPL or other license that is incompatible with OpenCV
  • The PxR is proposed to proper branch
  • There is refxerence to original bug report and related work
  • There is accuracy test, performance test and test data in opencv_extra repository, if applicable
    Patch to opencv_extra has the same branch name.
  • The feature is well documented and sample code can be built with the project CMake

@asmorkalov
Copy link
Copy Markdown
Contributor

@vpisarev Please take a look.

@vpisarev
Copy link
Copy Markdown
Contributor

vpisarev commented Nov 25, 2020

@chargerKong, the introduced operations are potentially dangerous, because there is no way to guarantee that "S" is scalar value, and it's not "cv::Scalar", "cv::Rect", "cv::Mat" etc. To resolve possible ambiguity, I suggest to add the following operations instead:

     template <typename T>
     friend Quat<T> cv::operator-(double, const Quat<T>&);

     template <typename T>
     friend Quat<T> cv::operator-(const Quat<T>&, double);

     template <typename T>
     friend Quat<T> cv::operator+(double, const Quat<T>&);

     template <typename T>
     friend Quat<T> cv::operator+(const Quat<T>&, double);

     template <typename T>
     friend Quat<T> cv::operator*(double, const Quat<T>&);

If needed, add the same operations for float scalar.

@chargerKong
Copy link
Copy Markdown
Contributor Author

chargerKong commented Nov 26, 2020

Thank you for your code review @vpisarev.

If "S" is not float or double or int, the implemetation of these functions will finally raise an error, because we have limited the elements for generating quaternion must be float or double. So I think maybe it's OK.

@vpisarev
Copy link
Copy Markdown
Contributor

vpisarev commented Nov 27, 2020

@chargerKong, right, but from our experience with template functions in OpenCV this is still a potential problem.

@chargerKong
Copy link
Copy Markdown
Contributor Author

chargerKong commented Nov 28, 2020

OK.

I have one last question.

What if we add some limitation in these funcition? @vpisarev

template <typename T, typename S>
inline Quat<T> operator+(const S a, const Quat<T>& q)
{
    static_assert(std::is_same<S, int>::value ||                 	   
                   std::is_same<S, double>::value ||                                                          
                   std::is_same<S, float>::value , "A quaternion only can be added with a scalar or a quaternion.");
    return Quat<T>(q.w + a, q.x, q.y, q.z);
}

@alalek
Copy link
Copy Markdown
Member

alalek commented Nov 28, 2020

IMHO, to avoid unclear operations (without documentation) it is better to introduce .addRotation() method (rotate() function) instead (due to angle/2 behavior and normalization tricks).

@chargerKong
Copy link
Copy Markdown
Contributor Author

Thanks for your code review @alalek

I want to stick to use these operators and could add the documentation in detail. Because these kind of operations are easy to read and understand. This is the symbols which we have used in papers and the daily writing by hand.

What do you think?

@vpisarev
Copy link
Copy Markdown
Contributor

vpisarev commented Nov 29, 2020

@chargerKong, if such a static_assert passes buildbot, i.e. compiles with every compiler that we use now, this is good solution.

Also, can you please add into the regression test at least one case where double scalar is added to floating-point quaternion, e.g. 1.3 + Quatf(1.f, 1.f, 1.f, 1.f)? I expect that some compilers will produce warnings for such operation because of missing type casts in the constructor calls.

@alalek
Copy link
Copy Markdown
Member

alalek commented Nov 29, 2020

<typename T, typename S>

IMHO, both types should be equal.

BTW, int => float conversion is not accurate.int support should be removed too.

@chargerKong
Copy link
Copy Markdown
Contributor Author

I agree with @alalek, and we could add the note: "The type of the scalar and the quaterinion should be equal" in the documentation.
What do you think about it? @vpisarev

@vpisarev
Copy link
Copy Markdown
Contributor

vpisarev commented Nov 30, 2020

@chargerKong, it's fine with me, it will also automatically eliminate my concerns about possible ambiguity in the future

@chargerKong chargerKong force-pushed the quat branch 2 times, most recently from 931c1e0 to c8bf0bf Compare December 2, 2020 02:00
Copy link
Copy Markdown
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for contribution!

//! @endcond

#endif /*OPENCV_CORE_QUATERNION_INL_HPP*/
#endif /*OPENCV_CORE_QUATERNION_INL_HPP*/ No newline at end of file
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please keep single empty "new line"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean to create a new empty line at the end?

Copy link
Copy Markdown
Member

@alalek alalek Dec 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, files should have with single "new line" symbol in the end (resolved)

@vpisarev
Copy link
Copy Markdown
Contributor

vpisarev commented Dec 2, 2020

👍

@vpisarev
Copy link
Copy Markdown
Contributor

vpisarev commented Dec 2, 2020

@chargerKong, could you, please, squash the commits into one:

$ git reset --soft HEAD~2
$ git commit
$ git push --force origin

fix a typo;
Add documentation of quaternion operators;
Restrict the type of scalar: the same as quaternion;
@vpisarev
Copy link
Copy Markdown
Contributor

vpisarev commented Dec 2, 2020

thank you!

@chargerKong chargerKong deleted the quat branch December 3, 2020 15:58
@alalek alalek mentioned this pull request Apr 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants