diff --git a/geometry.scad b/geometry.scad
index 73abe90..21b4f29 100644
--- a/geometry.scad
+++ b/geometry.scad
@@ -1074,6 +1074,7 @@ function distance_from_plane(plane, point) =
     let( plane = normalize_plane(plane) )
     point3d(plane)* point - plane[3];
 
+
 // Returns [POINT, U] if line intersects plane at one point.
 // Returns [LINE, undef] if the line is on the plane.
 // Returns undef if line is parallel to, but not on the given plane.
@@ -1596,7 +1597,6 @@ function circle_circle_tangents(c1,r1,c2,r2,d1,d2) =
     ];
 
 
-
 // Function: circle_line_intersection()
 // Usage:
 //   isect = circle_line_intersection(c,r,line,<bounded>,<eps>);
@@ -1629,7 +1629,6 @@ function circle_line_intersection(c,r,line,d,bounded=false,eps=EPSILON) =
              let( offset = sqrt(r*r-d*d),
                   uvec=unit(line[1]-line[0])
              ) [closest-offset*uvec, closest+offset*uvec]
-
   )
   [for(p=isect)
      if ((!bounded[0] || (p-line[0])*(line[1]-line[0])>=0)
@@ -1637,7 +1636,6 @@ function circle_line_intersection(c,r,line,d,bounded=false,eps=EPSILON) =
 
 
 
-
 // Section: Pointlists
 
 
@@ -1758,27 +1756,31 @@ function polygon_area(poly, signed=false) =
 // Usage:
 //   is_convex_polygon(poly);
 // Description:
-//   Returns true if the given 2D polygon is convex.  The result is meaningless if the polygon is not simple (self-intersecting).
-//   If the points are collinear the result is true.
+//   Returns true if the given 2D or 3D polygon is convex.  
+//   The result is meaningless if the polygon is not simple (self-intersecting) or non coplanar.
+//   If the points are collinear an error is generated.
 // Arguments:
 //   poly = Polygon to check.
 // Example:
 //   is_convex_polygon(circle(d=50));  // Returns: true
+//   is_convex_polygon(rot([50,120,30], p=path3d(circle(1,$fn=50)))); // Returns: true
 // Example:
 //   spiral = [for (i=[0:36]) let(a=-i*10) (10+i)*[cos(a),sin(a)]];
 //   is_convex_polygon(spiral);  // Returns: false
 function is_convex_polygon(poly) =
-    assert(is_path(poly,dim=2), "The input should be a 2D polygon." )
-    let( l = len(poly) )
-    len([for( i = l-1,
-              c = cross(poly[(i+1)%l]-poly[i], poly[(i+2)%l]-poly[(i+1)%l]),
-              s = sign(c);
-            i>=0 && sign(c)==s;
-              i = i-1,
-              c = i<0? 0: cross(poly[(i+1)%l]-poly[i],poly[(i+2)%l]-poly[(i+1)%l]),
-              s = s==0 ? sign(c) : s
-            ) i
-        ])== l;
+    assert(is_path(poly), "The input should be a 2D or 3D polygon." )
+    let( lp = len(poly),
+         p0 = poly[0] )
+    assert( lp>=3 , "A polygon must have at least 3 points" )
+    let( crosses = [for(i=[0:1:lp-1]) cross(poly[(i+1)%lp]-poly[i], poly[(i+2)%lp]-poly[(i+1)%lp]) ] )
+    len(p0)==2
+    ?   assert( !approx(max(crosses)) && !approx(min(crosses)), "The points are collinear" )
+        min(crosses) >=0 || max(crosses)<=0
+    :   let( prod = crosses*sum(crosses),
+             minc = min(prod),
+             maxc = max(prod) )
+        assert( !approx(maxc-minc), "The points are collinear" )
+        minc>=0 || maxc<=0;
 
 
 // Function: polygon_shift()
diff --git a/tests/test_geometry.scad b/tests/test_geometry.scad
index 0e70f31..492deb1 100644
--- a/tests/test_geometry.scad
+++ b/tests/test_geometry.scad
@@ -844,6 +844,7 @@ module test_polygon_area() {
 module test_is_convex_polygon() {
     assert(is_convex_polygon([[1,1],[-1,1],[-1,-1],[1,-1]]));
     assert(is_convex_polygon(circle(r=50,$fn=1000)));
+    assert(is_convex_polygon(rot([50,120,30], p=path3d(circle(1,$fn=50)))));
     assert(!is_convex_polygon([[1,1],[0,0],[-1,1],[-1,-1],[1,-1]]));
 }
 *test_is_convex_polygon();