I have recently used Vector2 for several functions, in some cases as Point and in some cases as Vector (dimension).

I have found that it is not the best especially if function parameters need both, point/s and vector/s.

I have created class Line which just has two points and an enum for line type (straight, ray, segment).

It was much better and safe however, it needs to create a line and sometimes you have just a point and vector or two points.

So another step is to split general sf::Vector2 into two types:

- Point2

- Vec2

And define operations over them. I found it as really big advantage as it can forbid meaningless operations.

Point2f pointA {1.f,1.f};

Point2f pointB {2.f,2.f};

Vec2f vecA {3.f, 0.f};

auto bLessA = pointB - pointA; // bLessA is Vec2f because operand- for two points are not defined

auto pointC = bLessA + vecA; // Error as there is no overloaded operand+ for two points

auto aAddVecA = pointA + vecA; // type is Point2f

This allows me to define function parameters much more safely (used C++20):

template <typename T>

concept arithmetic = std::integral<T> || std::floating_point<T>; // more strict definition to general definition

template <arithmetic T>

auto linesIntersection (const Point<T>& pointA, const Vec<T>& vecA, const Point<T> pointP, const Vec<T>& vecP)

-> std::optional<Point<T>>;

template <arithmetic T>

auto linesIntersection (const Point<T>& pointA, const Point<T>& pointB, const Point<T>& pointP, const Point<T>& pointQ)

-> std::optional<Point<T>>;

Would not be useful that type safety even for SFML?