aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2023-01-28 15:33:17 +0000
committerrodri <rgl@antares-labs.eu>2023-01-28 15:33:17 +0000
commit302a41f84da0884d1ac07d653868c7d0e7604362 (patch)
tree40e46d21437f9eb9bf38d2915185b8420c8c8112
parentfdeaa2423c582df8d9e9ae6b0e26d386b5531262 (diff)
downloadlibgeometry-302a41f84da0884d1ac07d653868c7d0e7604362.tar.gz
libgeometry-302a41f84da0884d1ac07d653868c7d0e7604362.tar.bz2
libgeometry-302a41f84da0884d1ac07d653868c7d0e7604362.zip
made edgeptcmp public. implemented centroid for Triangle[23], and a homogeneous-to-barycentric coordinates conversion function for Triangle2.
-rw-r--r--geometry.h7
-rw-r--r--point.c5
-rw-r--r--triangle.c33
3 files changed, 43 insertions, 2 deletions
diff --git a/geometry.h b/geometry.h
index efe1abe..ec4e8d1 100644
--- a/geometry.h
+++ b/geometry.h
@@ -56,6 +56,7 @@ Point2 lerp2(Point2, Point2, double);
double dotvec2(Point2, Point2);
double vec2len(Point2);
Point2 normvec2(Point2);
+int edgeptcmp(Point2, Point2, Point2);
int ptinpoly(Point2, Point2*, ulong);
/* Point3 */
@@ -118,8 +119,12 @@ Point3 rframexform3(Point3, RFrame3);
Point2 invrframexform(Point2, RFrame);
Point3 invrframexform3(Point3, RFrame3);
+/* Triangle2 */
+Point2 centroid(Triangle2);
+Point3 barycoords(Triangle2, Point2);
+
/* Triangle3 */
-Point3 centroid(Triangle3);
+Point3 centroid3(Triangle3);
/* Fmt */
#pragma varargck type "v" Point2
diff --git a/point.c b/point.c
index 91634f0..0267c41 100644
--- a/point.c
+++ b/point.c
@@ -79,6 +79,11 @@ normvec2(Point2 v)
*
* Juan Pineda, “A Parallel Algorithm for Polygon Rasterization”,
* Computer Graphics, Vol. 22, No. 8, August 1988
+ *
+ * comparison of a point p with an edge [e0 e1]
+ * p to the right: +
+ * p to the left: -
+ * p on the edge: 0
*/
int
edgeptcmp(Point2 e0, Point2 e1, Point2 p)
diff --git a/triangle.c b/triangle.c
index 3fc0cc9..1ed6cfc 100644
--- a/triangle.c
+++ b/triangle.c
@@ -2,8 +2,39 @@
#include <libc.h>
#include <geometry.h>
+/* 2D */
+
+Point2
+centroid(Triangle2 t)
+{
+ return divpt2(addpt2(t.p0, addpt2(t.p1, t.p2)), 3);
+}
+
+/*
+ * based on the implementation from:
+ *
+ * Dmitry V. Sokolov, “Tiny Renderer: Lesson 2”,
+ * https://github.com/ssloy/tinyrenderer/wiki/Lesson-2:-Triangle-rasterization-and-back-face-culling
+ */
+Point3
+barycoords(Triangle2 t, Point2 p)
+{
+ Point2 p0p1 = subpt2(t.p1, t.p0);
+ Point2 p0p2 = subpt2(t.p2, t.p0);
+ Point2 pp0 = subpt2(t.p0, p);
+
+ Point3 v = crossvec3(Vec3(p0p2.x, p0p1.x, pp0.x), Vec3(p0p2.y, p0p1.y, pp0.y));
+
+ /* handle degenerate triangles—i.e. the ones where every point lies on the same line */
+ if(fabs(v.z) < 1)
+ return Pt3(-1,-1,-1,1);
+ return Pt3(1 - (v.x + v.y)/v.z, v.y/v.z, v.x/v.z, 1);
+}
+
+/* 3D */
+
Point3
-centroid(Triangle3 t)
+centroid3(Triangle3 t)
{
return divpt3(addpt3(t.p0, addpt3(t.p1, t.p2)), 3);
}