From 5ff999c9bcb4c960c504058079403817a24b61ee Mon Sep 17 00:00:00 2001 From: ssloy Date: Thu, 22 Jan 2015 09:51:42 +0100 Subject: [PATCH] more careful rounding --- Makefile | 4 ++-- geometry.cpp | 12 ++++++++++++ geometry.h | 30 +++++++++++++++--------------- main.cpp | 11 +++++------ 4 files changed, 34 insertions(+), 23 deletions(-) create mode 100644 geometry.cpp diff --git a/Makefile b/Makefile index 25ceb793..31e19462 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ SYSCONF_LINK = g++ -CPPFLAGS = -LDFLAGS = +CPPFLAGS = -O3 +LDFLAGS = -O3 LIBS = -lm DESTDIR = ./ diff --git a/geometry.cpp b/geometry.cpp new file mode 100644 index 00000000..5d769e28 --- /dev/null +++ b/geometry.cpp @@ -0,0 +1,12 @@ +#include +#include +#include +#include +#include "geometry.h" + +template <> template <> Vec3::Vec3<>(const Vec3 &v) : x(int(v.x+.5)), y(int(v.y+.5)), z(int(v.z+.5)) { +} + +template <> template <> Vec3::Vec3<>(const Vec3 &v) : x(v.x), y(v.y), z(v.z) { +} + diff --git a/geometry.h b/geometry.h index 1a495e6b..b5081d34 100644 --- a/geometry.h +++ b/geometry.h @@ -4,12 +4,10 @@ #include template struct Vec2 { - t raw[2]; - t& x; - t& y; - Vec2() : raw(), x(raw[0]), y(raw[1]) { x = y = t(); } - Vec2(t _x, t _y) : raw(), x(raw[0]), y(raw[1]) { x=_x; y=_y; } - Vec2(const Vec2 &v) : raw(), x(raw[0]), y(raw[1]) { *this = v; } + t x, y; + Vec2() : x(t()), y(t()) {} + Vec2(t _x, t _y) : x(_x), y(_y) {} + Vec2(const Vec2 &v) : x(t()), y(t()) { *this = v; } Vec2 & operator =(const Vec2 &v) { if (this != &v) { x = v.x; @@ -20,18 +18,16 @@ template struct Vec2 { Vec2 operator +(const Vec2 &V) const { return Vec2(x+V.x, y+V.y); } Vec2 operator -(const Vec2 &V) const { return Vec2(x-V.x, y-V.y); } Vec2 operator *(float f) const { return Vec2(x*f, y*f); } - t& operator[](const int i) {return raw[i];} + t& operator[](const int i) { if (x<=0) return x; else return y; } template friend std::ostream& operator<<(std::ostream& s, Vec2& v); }; template struct Vec3 { - t raw[3]; - t& x; - t& y; - t& z; - Vec3() : raw(), x(raw[0]), y(raw[1]), z(raw[2]) { x = y = z = t(); } - Vec3(t _x, t _y, t _z) : raw(), x(raw[0]), y(raw[1]), z(raw[2]) { x=_x; y=_y; z=_z; } - Vec3(const Vec3 &v) : raw(), x(raw[0]), y(raw[1]), z(raw[2]) { *this = v; } + t x, y, z; + Vec3() : x(t()), y(t()), z(t()) { } + Vec3(t _x, t _y, t _z) : x(_x), y(_y), z(_z) {} + template Vec3(const Vec3 &v); + Vec3(const Vec3 &v) : x(t()), y(t()), z(t()) { *this = v; } Vec3 & operator =(const Vec3 &v) { if (this != &v) { x = v.x; @@ -47,7 +43,7 @@ template struct Vec3 { t operator *(const Vec3 &v) const { return x*v.x + y*v.y + z*v.z; } float norm () const { return std::sqrt(x*x+y*y+z*z); } Vec3 & normalize(t l=1) { *this = (*this)*(l/norm()); return *this; } - t& operator[](const int i) {return raw[i];} + t& operator[](const int i) { if (i<=0) return x; else if (i==1) return y; else return z; } template friend std::ostream& operator<<(std::ostream& s, Vec3& v); }; @@ -56,6 +52,10 @@ typedef Vec2 Vec2i; typedef Vec3 Vec3f; typedef Vec3 Vec3i; +template <> template <> Vec3::Vec3(const Vec3 &v); +template <> template <> Vec3::Vec3(const Vec3 &v); + + template std::ostream& operator<<(std::ostream& s, Vec2& v) { s << "(" << v.x << ", " << v.y << ")\n"; return s; diff --git a/main.cpp b/main.cpp index 93533f0b..e7223022 100644 --- a/main.cpp +++ b/main.cpp @@ -24,17 +24,16 @@ void triangle(Vec3i t0, Vec3i t1, Vec3i t2, TGAImage &image, TGAColor color, int int segment_height = second_half ? t2.y-t1.y : t1.y-t0.y; float alpha = (float)i/total_height; float beta = (float)(i-(second_half ? t1.y-t0.y : 0))/segment_height; // be careful: with above conditions no division by zero here - Vec3i A = t0 + (t2-t0)*alpha; - Vec3i B = second_half ? t1 + (t2-t1)*beta : t0 + (t1-t0)*beta; + Vec3i A = t0 + Vec3f(t2-t0)*alpha; + Vec3i B = second_half ? t1 + Vec3f(t2-t1)*beta : t0 + Vec3f(t1-t0)*beta; if (A.x>B.x) std::swap(A, B); for (int j=A.x; j<=B.x; j++) { float phi = B.x==A.x ? 1. : (float)(j-A.x)/(float)(B.x-A.x); - Vec3i P = A + (B-A)*phi; - P.x = j; P.y = t0.y+i; // a hack to fill holes (due to int cast precision problems) - int idx = j+(t0.y+i)*width; + Vec3i P = Vec3f(A) + Vec3f(B-A)*phi; + int idx = P.x+P.y*width; if (zbuffer[idx]