diff --git a/ex03/.gitignore b/ex03/.gitignore new file mode 100644 index 0000000..b3c7394 --- /dev/null +++ b/ex03/.gitignore @@ -0,0 +1 @@ +ex03 diff --git a/ex03/Fixed.cpp b/ex03/Fixed.cpp new file mode 100644 index 0000000..ba73d84 --- /dev/null +++ b/ex03/Fixed.cpp @@ -0,0 +1,144 @@ +#include "Fixed.hpp" +#include +#include + +const int Fixed::fracbits(8); + +Fixed::Fixed() { value = 0; } + +Fixed::Fixed(const int val) { value = val << fracbits; } + +Fixed::Fixed(const float val) { + const static int factor = 1 << fracbits; + float temp = (val * factor); + if (temp >= 0) + temp += 0.5f; + else + temp -= 0.5f; + value = (int)(temp); +} + +Fixed::Fixed(const Fixed &other) { this->value = other.value; } + +Fixed &Fixed::operator=(const Fixed &other) { + this->setRawBits(other.getRawBits()); + return *this; +} + +Fixed::~Fixed() {} + +int Fixed::getRawBits(void) const { return value; } + +void Fixed::setRawBits(int const raw) { value = raw; } + +float Fixed::toFloat(void) const { + const static int factor = 1 << fracbits; + float result = (float)value / factor; + return (result); +} + +int Fixed::toInt(void) const { + int result = (value >> fracbits); + return (result); +} + +std::string Fixed::toBin(void) const { + std::stringstream result; + result << std::bitset<32 - fracbits>(value >> fracbits); + result << "."; + result << std::bitset(value & (1 << fracbits) - 1); + return result.str(); +} + +bool Fixed::operator>(const Fixed &other) const { + return this->value > other.value; +} +bool Fixed::operator<(const Fixed &other) const { + return this->value < other.value; +} +bool Fixed::operator>=(const Fixed &other) const { + return this->value >= other.value; +} +bool Fixed::operator<=(const Fixed &other) const { + return this->value <= other.value; +} +bool Fixed::operator==(const Fixed &other) const { + return this->value == other.value; +} +bool Fixed::operator!=(const Fixed &other) const { + return this->value != other.value; +} + +const Fixed Fixed::operator+(const Fixed &other) const { + Fixed result = *this; + result.value += other.value; + return result; +} +const Fixed Fixed::operator-(const Fixed &other) const { + Fixed result = *this; + result.value -= other.value; + return result; +} +const Fixed Fixed::operator*(const Fixed &other) const { + Fixed result = *this; + result.value *= other.value; + result.value >>= fracbits; + return result; +} +const Fixed Fixed::operator/(const Fixed &other) const { + Fixed result = *this; + result.value /= other.value; + result.value <<= fracbits; + return result; +} +Fixed Fixed::operator++() { + this->value++; + return *this; +} +Fixed Fixed::operator--() { + this->value--; + return *this; +} +Fixed Fixed::operator++(int) { + Fixed result = *this; + operator++(); + return result; +} +Fixed Fixed::operator--(int) { + Fixed result = *this; + operator--(); + return result; +} + +Fixed &Fixed::min(Fixed &left, Fixed &right) { + if (left < right) + return left; + return right; +} +const Fixed &Fixed::min(const Fixed &left, const Fixed &right) { + if (left < right) + return left; + return right; +} +Fixed &Fixed::max(Fixed &left, Fixed &right) { + if (left > right) + return left; + return right; +} +const Fixed &Fixed::max(const Fixed &left, const Fixed &right) { + if (left > right) + return left; + return right; +} + +Fixed Fixed::abs() const { + Fixed result = *this; + if (result < 0) + return Fixed(0) - result; + return result; +} + +std::ostream &operator<<(std::ostream &stream, const Fixed &fixed) { + stream << fixed.toFloat(); + return stream; +} diff --git a/ex03/Fixed.hpp b/ex03/Fixed.hpp new file mode 100644 index 0000000..f7b1ca2 --- /dev/null +++ b/ex03/Fixed.hpp @@ -0,0 +1,53 @@ +#ifndef FIXED_HPP +#define FIXED_HPP + +#include + +class Fixed { +public: + Fixed(); + Fixed(const int val); + Fixed(const float val); + Fixed(const Fixed &other); + Fixed &operator=(const Fixed &other); + ~Fixed(); + + int getRawBits(void) const; + void setRawBits(int const raw); + + float toFloat(void) const; + int toInt(void) const; + + std::string toBin(void) const; + + bool operator>(const Fixed &other) const; + bool operator<(const Fixed &other) const; + bool operator>=(const Fixed &other) const; + bool operator<=(const Fixed &other) const; + bool operator==(const Fixed &other) const; + bool operator!=(const Fixed &other) const; + + const Fixed operator+(const Fixed &other) const; + const Fixed operator-(const Fixed &other) const; + const Fixed operator*(const Fixed &other) const; + const Fixed operator/(const Fixed &other) const; + Fixed operator++(); + Fixed operator--(); + Fixed operator++(int); + Fixed operator--(int); + + static Fixed &min(Fixed &left, Fixed &right); + static const Fixed &min(const Fixed &left, const Fixed &right); + static Fixed &max(Fixed &left, Fixed &right); + static const Fixed &max(const Fixed &left, const Fixed &right); + + Fixed abs() const; + + friend std::ostream &operator<<(std::ostream &stream, const Fixed &fixed); + +private: + int value; + static const int fracbits; +}; + +#endif diff --git a/ex03/Makefile b/ex03/Makefile new file mode 100644 index 0000000..0418e6e --- /dev/null +++ b/ex03/Makefile @@ -0,0 +1,41 @@ +NAME = ex03 +ifeq ($(CPPFLAGS),) + CPPFLAGS = -Wall -Wextra -Werror -std=c++98 -g +endif +ifeq ($(CXX),) + CXX = c++ +endif +# g++ is the default on 42 computers +ifeq ($(CXX),g++) + CXX = c++ +endif +srcs = \ + Fixed.cpp \ + Point.cpp \ + bsp.cpp \ + +main_objs = main.o $(srcs:.cpp=.o) +all_objs = $(main_objs) +deps = $(all_objs:.o=.d) + +all: $(NAME) + +-include $(deps) + +$(NAME): $(main_objs) + $(CXX) $(CPPFLAGS) -o $@ $^ + +%.o: %.cpp + $(CXX) -c $(CPPFLAGS) -o $*.o $*.cpp + $(CXX) -MM $(CPPFLAGS) -MT $*.o $*.cpp > $*.d + +clean: + find . -name '*.o' -print -delete + find . -name '*.d' -print -delete + +fclean: clean + rm -f $(NAME) + +re: + +make fclean + +make all diff --git a/ex03/Point.cpp b/ex03/Point.cpp new file mode 100644 index 0000000..89abd37 --- /dev/null +++ b/ex03/Point.cpp @@ -0,0 +1,24 @@ +#include "Point.hpp" +#include + +Point::Point() : x(0), y(0) {} +Point::Point(float x, float y) : x(Fixed(x)), y(Fixed(y)) {} +Point::Point(Point const &other) : x(other.x), y(other.y) {} +Point &Point::operator=(const Point &other) { + (void)other; + std::cerr << "WARNING: called Point::operator=, which is a noop due to x and " + "y being const." + << std::endl; + return *this; +}; +Point::~Point() {} + +Fixed Point::triangleArea(Point const &a, Point const &b, Point const &c) { + return (((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) / 2) + .abs(); +} + +std::ostream &operator<<(std::ostream &stream, const Point &p) { + stream << "(" << p.x << ", " << p.y << ")"; + return stream; +} diff --git a/ex03/Point.hpp b/ex03/Point.hpp new file mode 100644 index 0000000..79381d7 --- /dev/null +++ b/ex03/Point.hpp @@ -0,0 +1,25 @@ +#ifndef POINT_HPP +#define POINT_HPP + +#include "Fixed.hpp" + +class Point { +private: + const Fixed x; + const Fixed y; + +public: + Point(); + Point(float x, float y); + Point(Point const &other); + Point &operator=(const Point &other); + ~Point(); + + static Fixed triangleArea(Point const &a, Point const &b, Point const &c); + + friend std::ostream &operator<<(std::ostream &stream, const Point &point); +}; + +bool bsp(Point const a, Point const b, Point const c, Point const point); + +#endif diff --git a/ex03/bsp.cpp b/ex03/bsp.cpp new file mode 100644 index 0000000..8e4bba6 --- /dev/null +++ b/ex03/bsp.cpp @@ -0,0 +1,17 @@ +#include "Point.hpp" + +bool bsp(Point const a, Point const b, Point const c, Point const point) { + Fixed area = Point::triangleArea(a, b, c); + if (area == 0) + return false; + Fixed area1 = Point::triangleArea(point, a, b); + if (area1 == 0) + return false; + Fixed area2 = Point::triangleArea(point, b, c); + if (area2 == 0) + return false; + Fixed area3 = Point::triangleArea(point, a, c); + if (area3 == 0) + return false; + return area1 + area2 + area3 == area; +} diff --git a/ex03/main.cpp b/ex03/main.cpp new file mode 100644 index 0000000..93e0411 --- /dev/null +++ b/ex03/main.cpp @@ -0,0 +1,17 @@ +#include "Point.hpp" + +static void assert_bsp(Point a, Point b, Point c, Point p, bool expected) { + bool result = bsp(a, b, c, p); + std::cout << "a: " << a << "\tb: " << b << "\tc: " << c << "\tp: " << p; + std::cout << "\tresult: " << result << " expected: " << expected << std::endl; + if (result != expected) + throw 0; +} + +int main(void) { + assert_bsp(Point(0, 0), Point(20, 0), Point(10, 30), Point(10, 15), true); + assert_bsp(Point(0, 0), Point(0, 0), Point(0, 0), Point(0, 0), false); + assert_bsp(Point(0, 0), Point(20, 0), Point(30, 0), Point(15, 0), false); + assert_bsp(Point(0, 0), Point(20, 0), Point(30, 10), Point(15, 10.1f), false); + return 0; +}