定义Point类,即点,同时也可以作为平面向量使用。Point的加减乘除是作为向量的加减乘除。
下面给出Point的声明。
class Point : public Geometry
{
public:
double x = 0;
double y = 0;
public:
Point() {};
Point(const double x_, const double y_);
Point(const Point &point);
Point(const MarkedPoint &point);
Point &operator=(const Point &point);
const Type type() const override;
const bool operator==(const Point &point) const;
const bool operator!=(const Point &point) const;
const Point &normalize();
Point normalized() const;
// 获取左侧的垂直向量
Point vertical() const;
// 向量模长
const double length() const override;
// 判断是否为零向量
const bool empty() const override;
// 变为零向量
void clear() override;
Point *clone() const override;
void transform(const double a, const double b, const double c, const double d, const double e, const double f) override;
void transform(const double mat[6]) override;
void translate(const double tx, const double ty) override;
void rotate(const double x_, const double y_, const double rad) override;
void scale(const double x_, const double y_, const double k) override;
AABBRect bounding_rect() const override;
Polygon mini_bounding_rect() const override;
Point operator*(const double k) const;
// 向量点积
double operator*(const Point &point) const;
// 向量叉积
double cross(const Point &point) const;
Point operator+(const Point &point) const;
Point operator-(const Point &point) const;
Point operator/(const double k) const;
void operator*=(const double k);
void operator+=(const Point &point);
void operator-=(const Point &point);
void operator/=(const double k);
};
using Vector = Point;
下面给出Point的实现。
Point::Point(const double x_, const double y_)
: x(x_), y(y_)
{}
Point::Point(const Point &point)
:Geometry(point), x(point.x), y(point.y)
{}
Point::Point(const MarkedPoint &point)
: x(point.x), y(point.y)
{}
Point &Point::operator=(const Point &point)
{
if (this != &point)
{
Geometry::operator=(point);
x = point.x;
y = point.y;
}
return *this;
}
const Type Point::type() const
{
return Type::POINT;
}
const bool Point::operator==(const Point &point) const
{
return x == point.x && y == point.y;
}
const bool Point::operator!=(const Point &point) const
{
return x != point.x || y != point.y;
}
const Point &Point::normalize()
{
const double len = length();
x /= len;
y /= len;
return *this;
}
Point Point::normalized() const
{
const double len = length();
return Point(x / len, y / len);
}
Point Point::vertical() const
{
return Point(-y, x);
}
const double Point::length() const
{
return std::sqrt(x * x + y * y);
}
const bool Point::empty() const
{
return x == 0 && y == 0;
}
void Point::clear()
{
x = 0;
y = 0;
}
Point *Point::clone() const
{
return new Point(*this);
}
void Point::transform(const double a, const double b, const double c, const double d, const double e, const double f)
{
const double x_ = x, y_ = y;
x = a * x_ + b * y_ + c;
y = d * x_ + e * y_ + f;
}
void Point::transform(const double mat[6])
{
const double x_ = x, y_ = y;
x = mat[0] * x_ + mat[1] * y_ + mat[2];
y = mat[3] * x_ + mat[4] * y_ + mat[5];
}
void Point::translate(const double tx, const double ty)
{
x += tx;
y += ty;
}
void Point::rotate(const double x_, const double y_, const double rad)
{
x -= x_;
y -= y_;
const double x1 = x, y1 = y;
x = x1 * std::cos(rad) - y1 * std::sin(rad);
y = x1 * std::sin(rad) + y1 * std::cos(rad);
x += x_;
y += y_;
}
void Point::scale(const double x_, const double y_, const double k)
{
const double x1 = x, y1 = y;
x = k * x1 + x_ * (1 - k);
y = k * y1 + y_ * (1 - k);
}
AABBRect Point::bounding_rect() const
{
if (length() == 0)
{
return AABBRect();
}
else
{
return AABBRect(std::min(0.0, x), std::min(0.0, y), std::max(0.0, x), std::max(0.0, y));
}
}
Polygon Point::mini_bounding_rect() const
{
if (length() == 0)
{
return Polygon();
}
else
{
return AABBRect(std::min(0.0, x), std::min(0.0, y), std::max(0.0, x), std::max(0.0, y));
}
}
Point Point::operator*(const double k) const
{
return Point(x * k, y * k);
}
double Point::operator*(const Point &point) const
{
return x * point.x + y * point.y;
}
double Point::cross(const Point &point) const
{
return x * point.y - y * point.x;
}
Point Point::operator+(const Point &point) const
{
return Point(x + point.x, y + point.y);
}
Point Point::operator-(const Point &point) const
{
return Point(x - point.x, y - point.y);
}
Point Point::operator/(const double k) const
{
return Point(x / k, y / k);
}
void Point::operator*=(const double k)
{
x *= k;
y *= k;
}
void Point::operator+=(const Point &point)
{
x += point.x;
y += point.y;
}
void Point::operator-=(const Point &point)
{
x -= point.x;
y -= point.y;
}
void Point::operator/=(const double k)
{
x /= k;
y /= k;
}