Commit b741b613 authored by Yann Niclass's avatar Yann Niclass
Browse files

add point class from TP03

complete interval.h
complete intervalTree.h
complete rangeTree.cpp (except search part)
parent 705ed206
......@@ -6,7 +6,69 @@
#define CPPALGO_INTERVAL_H
//TODO: Need to implement this part
template<typename T1 = int, typename T2 = double>
class Interval {
public:
Interval(T1 start, T1 end, T2 value = 0) : start_(start), end_(end), value_(value) {}
T1 getStart() const { return start_; }
T1 getEnd() const { return end_; }
T2 getValue() const { return value_; }
//Overload Operators
bool operator==(const Interval &other) const {
return value_ == other.value_;
}
bool operator!=(const Interval &other) const {
return !(this == other);
}
bool contains(const T2 value) const {
return start_ <= value_ && value_ <= end_;
}
// float
template<typename T>
bool operator==(const Interval<float, T> &other) const {
return abs(start_ - other.start_) < std::numeric_limits<float>::epsilon() &&
abs(end_ - other.end_) < std::numeric_limits<float>::epsilon() &&
value_ == other.value_;
}
template<typename T>
bool operator==(const Interval<T, float> &other) const {
return start_ == other.start_ &&
end_ == other.end_ &&
abs(value_ - other.value_) < std::numeric_limits<float>::epsilon();
}
// double
template<typename T>
bool operator==(const Interval<double, T> &other) const {
return abs(start_ - other.getStart()) < std::numeric_limits<double>::epsilon() &&
abs(end_ - other.getEnd()) < std::numeric_limits<double>::epsilon() &&
value_ == other.getValue();
}
template<typename T>
bool operator==(const Interval<T, double> &other) const {
return start_ == other.start_ &&
end_ == other.end_&&
abs(value_ - other.value_) < std::numeric_limits<double>::epsilon();
}
private:
T1 start_;
T1 end_;
T2 value_;
};
#endif //CPPALGO_INTERVAL_H
......@@ -73,7 +73,11 @@ void IntervalTree<T>::intersecting(std::vector<Interval<T>> &solution,
//Add intervals from current node that intersect
//Handle left/right children
//TODO: Need to implement this part
for (auto &interval: node->value.intersecting(x)) {
solution.push_back(interval);
}
intersecting(solution, (*node).left, x);
intersecting(solution, (*node).right, x);
}
template<typename T>
......@@ -99,12 +103,33 @@ IntervalTree<T>::fromIntervals(const std::vector<Interval<T>> &intervals,
std::vector<Interval<T>> rightPart;
//Split intervals to left, mid, right
//Create new BinaryTreeNode
//Initialize/Build left and right child of that new node
//Return the new node
//TODO: Need to implement this part
//Split intervals to left, mid, right OK
//Create new BinaryTreeNode OK
//Initialize/Build left and right child of that new node OK
//Return the new node OK
for (const Interval<T> &interval: intervals) {
if (interval.contains(mid)) {
midPart.push_back(interval);
} else if (interval.getEnd() < mid) {
leftPart.push_back(interval);
} else {
rightPart.push_back(interval);
}
}
auto midElement = IntervalTreeElement<T>(midPart, mid);
//TODO : Need to implement IntervalTreeElement.h to construct this (WIP)
BinaryTreeNode<IntervalTreeElement<T>, T> *node = new BinaryTreeNode<IntervalTreeElement<T>,
T>(mid, midElement,parent);
(*node).left = fromIntervals(leftPart, node);
(*node).right = fromIntervals(rightPart, node);
return node;
}
#endif //CPPALGO_INTERVALTREE_H
//
// Created by Niclass Yann on 01.05.2022.
// HEIA-FR 2022
//
#include "Point.h"
Point::Point(const Point &p) : x(p.x), y(p.y), name(p.name) {}
Point::Point(double x, double y, std::string name) : x(x), y(y), name(name) {}
Point::~Point() = default;
double Point::getX() const {
return x;
}
double Point::getY() const {
return y;
}
void Point::setX(double x1) {
Point::x = x1;
}
void Point::setY(double y1) {
Point::y = y1;
}
std::string Point::getName() {
return name;
}
double Point::distance(const Point &point) const {
// Don't use sqrt() here, it's slow
return pow(point.getX() - x, 2) + pow(point.getY() - y, 2);
}
Point &Point::operator+=(const Point &other) {
x += other.getX();
y += other.getY();
return *this;
}
Point &Point::operator-=(const Point &other) {
x -= other.getX();
y -= other.getY();
return *this;
}
Point &Point::operator*=(double other) {
x *= other;
y *= other;
return *this;
}
Point &Point::operator/=(double other) {
if (other == 0) {
throw std::invalid_argument("Division by zero");
}
x /= other;
y /= other;
return *this;
}
Point Point::operator+(Point &other) {
return Point(x + other.getX(), y + other.getY());
}
Point Point::operator-(Point &other) {
return Point(x - other.getX(), y - other.getY());
}
Point Point::operator*(double other) {
return Point(x * other, y * other);
}
Point Point::operator/(double other) {
if (other == 0) {
throw std::invalid_argument("Division by zero");
}
return Point(x / other, y / other);
}
//
// Created by Niclass Yann on 01.05.2022.
// HEIA-FR 2022
//
#ifndef TP4_POINT_H
#define TP4_POINT_H
#include <functional>
#include <unordered_set>
#include <ostream>
#include <random>
/**
* Simple 2D point using doubles. The point can have an optional name.
* The point implements basic operators to manipulate the point, as well as
*/
class Point {
public:
Point() : x(0), y(0) { name = ""; }
Point(const Point &point);
Point(double x, double y, std::string name = "");
virtual ~Point();
virtual double getX() const;
virtual double getY() const;
std::string getName();
virtual void setX(double x);
virtual void setY(double y);
virtual double distance(const Point &point) const;
virtual Point &operator+=(const Point &other);
virtual Point &operator-=(const Point &other);
virtual Point &operator*=(double other);
virtual Point &operator/=(double other);
virtual Point operator+(Point &other);
virtual Point operator-(Point &other);
virtual Point operator*(double other);
virtual Point operator/(double other);
protected:
double x{}, y{};
std::string name;
};
//Needs to be inline if defined in header
std::ostream &operator<<(std::ostream &os, const Point &point);
/**
* Hashing class that allows to create a hash of a Point easily
*/
class PointHash {
public:
std::size_t operator()(const Point *point) const {
std::size_t h1 = std::hash<double>{}(point->getX());
std::size_t h2 = std::hash<double>{}(point->getY());
return h1 ^ (h2 << 1); // or use boost::hash_combine
}
};
/**
* Create a certain amount of random Points in a specified interval
* @param count number of points to create
* @param min minimum x and y value
* @param max maximum x and y value
* @param seed seed to be used to rng, -1 to not seed the rng
* @return
*/
inline std::vector<Point *> createRandomPoints(size_t count, double min, double max, int seed = -1) {
std::mt19937 random_engine;
if (seed == -1) {
std::random_device random_device;
random_engine = std::mt19937(random_device());
} else {
random_engine = std::mt19937(seed);
}
std::uniform_int_distribution<int> distribution(min, max);
std::unordered_set<Point *, PointHash> point_set;
while (point_set.size() < count) {
point_set.insert(new Point(distribution(random_engine), distribution(random_engine)));
}
return {point_set.begin(), point_set.end()};
}
#endif //TP4_POINT_H
......@@ -6,7 +6,12 @@
RangeTree::RangeTree(std::vector<Point*> points){
//Sort all points by X
//TODO: Need to implement this part
std::sort(points.begin(), points.end(), [](Point *a, Point *b) {
bool pointsCompare = false;
if(a->getX() <= b->getX())
pointsCompare = true;
return pointsCompare;
});
//Build using all points (sorted in X)
this->xTree = build2DRangeTree(points, 0, points.size());
......@@ -34,8 +39,9 @@ BinaryTree<BinaryTree<Point*, double>, Point*> RangeTree::build2DRangeTree(std::
//build left and right children
//WARNING: build2DRangeTree returns a temporary BinaryTree.
//Use getRootCopy() to get a copy of the root node
//TODO: Need to implement this part
(*tx.getRoot()).left = build2DRangeTree(points, left, mid).getRootCopy();
(*tx.getRoot()).right = build2DRangeTree(points, mid, right).getRootCopy();
return tx;
}
......@@ -64,7 +70,6 @@ void RangeTree::search(std::vector<Point *> &result,
double yFrom, double yTo) const{
if(node != nullptr){ //node is nullptr if we are at the bottom of the tree
//TODO: Need to implement this part
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment