Skip to content

File Coordinate.h

File List > src > Coordinate.h

Go to the documentation of this file

// Copyright (c) 2012-2013, IGN France.
// Copyright (c) 2012-2022, Oslandia.
// SPDX-License-Identifier: LGPL-2.0-or-later

#ifndef _SFCGAL_COORDINATE_H_
#define _SFCGAL_COORDINATE_H_

#include "SFCGAL/config.h"

#include <boost/array.hpp>
#include <boost/assert.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/variant.hpp>

#include "SFCGAL/numeric.h"

#include "SFCGAL/Kernel.h"

namespace SFCGAL {

class SFCGAL_API Coordinate {
public:
  Coordinate();

  Coordinate(const Kernel::FT &x, const Kernel::FT &y);
  Coordinate(const Kernel::FT &x, const Kernel::FT &y, const Kernel::FT &z);

  Coordinate(const double &x, const double &y, const double &z);

  Coordinate(const double &x, const double &y);
  Coordinate(const Kernel::Point_2 &other);
  Coordinate(const Kernel::Point_3 &other);

  Coordinate(const Coordinate &other);
  Coordinate &
  operator=(const Coordinate &other);
  ~Coordinate();

  int
  coordinateDimension() const;
  bool
  isEmpty() const;
  bool
  is3D() const;

  //--- accessors

  Kernel::FT
  x() const;

  Kernel::FT
  y() const;

  Kernel::FT
  z() const;

  //-- helper

  Coordinate &
  round(const long &scaleFactor = 1);

  //-- comparator

  bool
  operator<(const Coordinate &other) const;

  bool
  operator==(const Coordinate &other) const;
  bool
  operator!=(const Coordinate &other) const;

  bool
  almostEqual(const Coordinate &other, const double tolerance) const;

  inline Kernel::Vector_2
  toVector_2() const
  {
    return Kernel::Vector_2(CGAL::ORIGIN, toPoint_2());
  }

  inline Kernel::Vector_3
  toVector_3() const
  {
    return Kernel::Vector_3(CGAL::ORIGIN, toPoint_3());
  }

  Kernel::Point_2
  toPoint_2() const;

  Kernel::Point_3
  toPoint_3() const;

  // class for Empty coordinate
  class Empty {};

private:
  boost::variant<Empty, Kernel::Point_2, Kernel::Point_3> _storage;

public:
  template <class Archive>
  void
  save(Archive &ar, const unsigned int /*version*/) const
  {
    int dim = coordinateDimension();
    ar << dim;

    if (_storage.which() > 0) {
      const Kernel::FT &x_ = x();
      const Kernel::FT &y_ = y();
      ar << x_;
      ar << y_;

      if (_storage.which() == 2) {
        const Kernel::FT &z_ = z();
        ar << z_;
      }
    }
  }

  template <class Archive>
  void
  load(Archive &ar, const unsigned int /*version*/)
  {
    int dim;
    ar >> dim;

    if (dim == 0) {
      _storage = Empty();
    } else if (dim == 2) {
      Kernel::FT x_, y_;
      ar >> x_;
      ar >> y_;
      _storage = Kernel::Point_2(x_, y_);
    } else if (dim == 3) {
      Kernel::FT x_, y_, z_;
      ar >> x_;
      ar >> y_;
      ar >> z_;
      _storage = Kernel::Point_3(x_, y_, z_);
    }
  }

  template <class Archive>
  void
  serialize(Archive &ar, const unsigned int version)
  {
    boost::serialization::split_member(ar, *this, version);
  }
};

} // namespace SFCGAL

#endif