Ну как бы геттеры/сеттеры защищают от тупых ошибок и для этого и нужны. rx() случайно сложно написать.
Шансы перепутать rx() <-> ry() те же самые что и x <-> y
В одном проекте такой подход к геометрии видел. Шаблонные алгоритмы (построение остова, r-дерево) работали не только с прямоугольниками, но и с любыми объектами имеющими bounding box. При этом обычный прямоугольник тоже снабдили абсурдным на первый взгляд метеодом rect bbox () const {return *this;}. Более гибко получается, любой объект может "притвориться" точкой или прямоугольником безо всякого наследования (типа как в питоне duck typing).
Для таких игр нужны классы "выше травы", а Point2D таким не является. Заметим что Point3D никогда не наследуется от Point2D, так же как и "Point4D" (кватернион) от Point3D. Неудачна даже попытка запихнуть его в template, напр
C++ (Qt)
template <class T>
class TPoint {
..
T x, y;
};
И вроде есть варианты (int, float, double) но на деле только куча неудобств
Др. словами мощность такого класса слишком мала чтобы он мог что-то решать, это пассивные данные к которым все имеют прямой доступ. А если так чего тогда притворяться с get/set ?
И дело не в том "как меньше записать" и, конечно, аксессоры никак не снизят скорость. Приятно работать с кодом где все "имеет смысл" , т.е. если человек сделал private, значит он что-то имел ввиду. А где просто налеплено get/set - логика класса не видна, и, как ни странно, эффект тот же самый что и все "public".