diff --git a/src/lib/mod.rs b/src/lib/mod.rs
index 7c2464c8ad7371b19babdd14e87d7753a6da9774..b49f9a89062516d64cf9fdc2a46596f779a9f0b7 100644
--- a/src/lib/mod.rs
+++ b/src/lib/mod.rs
@@ -31,12 +31,24 @@ impl IEDGE {
     }
 }
 
+#[derive(Debug)]
+pub enum TriangulationError {
+    NotEnoughPoints,
+    InvalidTriangulation,
+}
+
 /// Triangulation subroutine.
 /// Allows one to triangulate a list of points in a O(n²) time complexity
-pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, ntri: &mut i32) -> i32 {
+pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>) -> Result<Vec<ITRIANGLE>, TriangulationError> {
+    if *nv < 3 {
+        return Err(TriangulationError::NotEnoughPoints)
+    }
+    
     let trimax = 4 * *nv;
     let mut _nedge: i32 = 0;
-    let mut status = 0;
+
+    let mut v: Vec<ITRIANGLE> = vec![ITRIANGLE::new(-1, -1, -1); trimax as usize];
+    let mut ntri: i32 = 0;
     
     let mut edges: Vec<IEDGE> = Vec::with_capacity(100000_usize);
     let mut complete: Vec<bool> = vec![false; trimax as usize];
@@ -102,7 +114,7 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt
     v[0].p2 = *nv+1;
     v[0].p3 = *nv+2;
     complete[0] = false;
-    *ntri = 1;
+    ntri = 1;
 
     /*
         Include each point one at a time into the existing mesh
@@ -121,7 +133,7 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt
         */
 
         _j = 0;
-        while _j < *ntri as isize {
+        while _j < ntri as isize {
             if complete[_j as usize] {
                 _j += 1;
                 continue;
@@ -142,9 +154,9 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt
                 edges.push(IEDGE::new(v[_j as usize].p2, v[_j as usize].p3));
                 edges.push(IEDGE::new(v[_j as usize].p3, v[_j as usize].p1));
                 _nedge += 3;
-                v[_j as usize] = v[(*ntri-1) as usize];
-                complete[_j as usize] = complete[(*ntri-1) as usize];
-                *ntri -= 1;
+                v[_j as usize] = v[(ntri-1) as usize];
+                complete[_j as usize] = complete[(ntri-1) as usize];
+                ntri -= 1;
 
                 _j -= 1;
             }
@@ -188,15 +200,14 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt
                 _j += 1;
                 continue;
             }
-            if (*ntri) >= trimax {
-                status = 4;
-                return status
+            if (ntri) >= trimax {
+                return Err(TriangulationError::InvalidTriangulation);
             }
-            v[*ntri as usize].p1 = edges[_j as usize].p1;
-            v[*ntri as usize].p2 = edges[_j as usize].p2;
-            v[*ntri as usize].p3 = i as i32;
-            complete[*ntri as usize] = false;
-            *ntri += 1;
+            v[ntri as usize].p1 = edges[_j as usize].p1;
+            v[ntri as usize].p2 = edges[_j as usize].p2;
+            v[ntri as usize].p3 = i as i32;
+            complete[ntri as usize] = false;
+            ntri += 1;
             _j += 1;
         }
 
@@ -207,11 +218,11 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt
         These are triangles which have a vertex number greater than nv
     */
     let mut i: isize = 0_isize;
-    while (i as i32) < *ntri {
+    while (i as i32) < ntri {
         if v[i as usize].p1 >= *nv  || v[i as usize].p2 >= *nv || v[i as usize].p3 >= *nv
         {
             v.remove(i as usize);
-            *ntri -= 1;
+            ntri -= 1;
             i -=1 ;
         }
         i += 1;
@@ -219,7 +230,7 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt
 
     // Removing unnecessary triangles
     i = v.len() as isize - 1;
-    while (i as i32) >= *ntri {
+    while (i as i32) >= ntri {
         v.remove(i as usize);
         i -= 1;
     }
@@ -229,7 +240,7 @@ pub fn triangulate(nv: &mut i32, pxyz: &mut Vec<XYZ>, v: &mut Vec<ITRIANGLE>, nt
     pxyz.remove(pxyz.len()-1);
     pxyz.remove(pxyz.len()-1);
 
-    status
+    Ok(v)
 }
 
 /// Return true if a point (xp,yp) lies inside the circumcircle made up
@@ -290,7 +301,7 @@ fn circum_circle(xp: f64, yp: f64, x1: f64, y1: f64, x2: f64, y2: f64, x3: f64,
     drsqr = dx*dx + dy*dy;
 
     // Original
-    //return((drsqr <= *rsqr) ? TRUE : FALSE);
+    // return((drsqr <= *rsqr) ? TRUE : FALSE);
     // Proposed by Chuck Morris
     return (drsqr - *rsqr) <= EPSILON;
 }
diff --git a/src/main.rs b/src/main.rs
index 1540805fc20773685b532ebad5c51869527c3732..69af20ab76aad6a727c8d6f916bbec832a63f0c7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -8,7 +8,7 @@ mod lib;
 mod stl_writer;
 
 use las::reader::*;
-use lib::{XYZ, ITRIANGLE,triangulate};
+use lib::{XYZ, TriangulationError, ITRIANGLE, triangulate};
 
 use std::time::Instant;
 
@@ -27,12 +27,10 @@ fn main() {
     points.sort_by(|a, b| a.partial_cmp(b).unwrap());
 
     let mut nv: i32 = points.len() as i32;
-    let mut triangles: Vec<ITRIANGLE> = vec![ITRIANGLE::new(-1, -1, -1); 3*nv as usize];
-    let mut ntri: i32 = triangles.len() as i32;
 
     println!("triangulating {} points ...", points.len());
     let start_triangulation = Instant::now();
-    triangulate(&mut nv, &mut points, &mut triangles, &mut ntri);
+    let triangles: Vec<ITRIANGLE> = triangulate(&mut nv, &mut points).expect("An error has been detected while triangulating");
     let time_taken = start_triangulation.elapsed();
     
     println!("time taken to triangulate {} points : {} [s]", points.len(), time_taken.as_secs_f64());