Index: src/Shapes/BaseShapes.cpp
===================================================================
--- src/Shapes/BaseShapes.cpp	(revision 52575c82d0127ae0f5a1d9fa134d452d2069a4d3)
+++ src/Shapes/BaseShapes.cpp	(revision 0eb8f45f1e1939cbfd3df7516d7961efabb4b05a)
@@ -29,4 +29,5 @@
 #include "CodePatterns/Assert.hpp"
 #include "LinearAlgebra/Vector.hpp"
+#include "LinearAlgebra/RealSpaceMatrix.hpp"
 #include "LinearAlgebra/Line.hpp"
 #include "LinearAlgebra/Plane.hpp"
@@ -36,4 +37,94 @@
 #include <cmath>
 #include <algorithm>
+
+// CYLINDER CODE
+// ----------------------------------------------------------------------------
+bool Cylinder_impl::isInside(const Vector &point) const {
+  return (Vector(point[0], point[1], 0.0).NormSquared() < 1.0+MYEPSILON) &&
+      (point[2] > -1.0-MYEPSILON) && (point[2] < 1.0+MYEPSILON);
+}
+
+bool Cylinder_impl::isOnSurface(const Vector &point) const {
+  return fabs(Vector(point[0], point[1], 0.0).NormSquared()-1.0)<MYEPSILON &&
+      (point[2] > -1.0-MYEPSILON) && (point[2] < 1.0+MYEPSILON);
+
+}
+
+Vector Cylinder_impl::getNormal(const Vector &point) const throw(NotOnSurfaceException) {
+  if(!isOnSurface(point)){
+    throw NotOnSurfaceException() << ShapeVector(&point);
+  }
+
+  if ((fabs(point[2]-1)<MYEPSILON) || (fabs(point[2])<MYEPSILON))
+      return Vector(0.0, 0.0, point[2]);
+  else
+    return Vector(point[0], point[1], 0.0);
+}
+
+Vector Cylinder_impl::getCenter() const
+{
+  return Vector(0.0, 0.0, 0.0);
+}
+
+double Cylinder_impl::getRadius() const
+{
+    return 1.0;
+}
+
+double Cylinder_impl::getVolume() const
+{
+	return M_PI*2.0; // pi r^2 h
+}
+
+double Cylinder_impl::getSurfaceArea() const
+{
+	return 2.0*M_PI*2.0; // 2 pi r h
+}
+
+LineSegmentSet Cylinder_impl::getLineIntersections(const Line &line) const {
+    // TODO
+	ASSERT(0, "Cylinder_impl::getLineIntersections - not implemented.");
+}
+
+std::string Cylinder_impl::toString() const
+{
+  return "Cylinder()";
+}
+
+enum ShapeType Cylinder_impl::getType() const
+{
+	return CylinderType;
+}
+
+std::vector<Vector> Cylinder_impl::getHomogeneousPointsOnSurface(const size_t N) const {
+    // TODO
+    ASSERT(0, "Cylinder_impl::getHomogeneousPointsOnSurface - not implemented.");
+}
+
+std::vector<Vector> Cylinder_impl::getHomogeneousPointsInVolume(const size_t N) const {
+    // TODO
+    ASSERT(0, "Cylinder_impl::getHomogeneousPointsInVolume - not implemented.");
+}
+
+Shape Cylinder() {
+  Shape::impl_ptr impl = Shape::impl_ptr(new Cylinder_impl());
+  return Shape(impl);
+}
+
+Shape Cylinder(const Vector &center, const double xrot, const double yrot,
+        const double height, const double radius)
+{
+    RealSpaceMatrix rot;
+    rot.setRotation(xrot, yrot, 0.0);
+
+    return translate(
+                transform(
+                    stretch(
+                        Cylinder(),
+                    Vector(radius, radius, height*0.5)),
+                rot),
+            center);
+}
+// ----------------------------------------------------------------------------
 
 bool Sphere_impl::isInside(const Vector &point) const{
Index: src/Shapes/BaseShapes.hpp
===================================================================
--- src/Shapes/BaseShapes.hpp	(revision 52575c82d0127ae0f5a1d9fa134d452d2069a4d3)
+++ src/Shapes/BaseShapes.hpp	(revision 0eb8f45f1e1939cbfd3df7516d7961efabb4b05a)
@@ -17,4 +17,7 @@
 #include "Shapes/Shape.hpp"
 
+Shape Cylinder();
+Shape Cylinder(const Vector &center, const double xrot, const double yrot,
+        const double height, const double radius);
 Shape Sphere();
 Shape Sphere(const Vector &center,double radius);
Index: src/Shapes/BaseShapes_impl.hpp
===================================================================
--- src/Shapes/BaseShapes_impl.hpp	(revision 52575c82d0127ae0f5a1d9fa134d452d2069a4d3)
+++ src/Shapes/BaseShapes_impl.hpp	(revision 0eb8f45f1e1939cbfd3df7516d7961efabb4b05a)
@@ -21,4 +21,19 @@
 #include "Shapes/ShapeExceptions.hpp"
 #include "Shapes/ShapeType.hpp"
+
+class Cylinder_impl : public Shape_impl {
+  virtual bool isInside(const Vector &point) const;
+  virtual bool isOnSurface(const Vector &point) const;
+  virtual Vector getNormal(const Vector &point) const throw(NotOnSurfaceException);
+  virtual Vector getCenter() const;
+  virtual double getRadius() const;
+  virtual double getVolume() const;
+  virtual double getSurfaceArea() const;
+  virtual LineSegmentSet getLineIntersections(const Line&) const;
+  virtual std::string toString() const;
+  virtual enum ShapeType getType() const;
+  virtual std::vector<Vector> getHomogeneousPointsOnSurface(const size_t N) const;
+  virtual std::vector<Vector> getHomogeneousPointsInVolume(const size_t N) const;
+};
 
 class Sphere_impl : public Shape_impl {
Index: src/Shapes/ShapeType.hpp
===================================================================
--- src/Shapes/ShapeType.hpp	(revision 52575c82d0127ae0f5a1d9fa134d452d2069a4d3)
+++ src/Shapes/ShapeType.hpp	(revision 0eb8f45f1e1939cbfd3df7516d7961efabb4b05a)
@@ -22,5 +22,6 @@
 	PolygonType,
 	CombinedType,
-	MAX_ShapeType
+	MAX_ShapeType,
+    CylinderType
 };
 
Index: src/Shapes/unittests/BaseShapesUnitTest.cpp
===================================================================
--- src/Shapes/unittests/BaseShapesUnitTest.cpp	(revision 52575c82d0127ae0f5a1d9fa134d452d2069a4d3)
+++ src/Shapes/unittests/BaseShapesUnitTest.cpp	(revision 0eb8f45f1e1939cbfd3df7516d7961efabb4b05a)
@@ -78,4 +78,86 @@
 {}
 
+void BaseShapesTest::cylinderTest()
+{
+    Shape s = Cylinder();
+    // z = 0
+    // Quadrant 1 1
+    CPPUNIT_ASSERT( s.isInside(v000));
+    CPPUNIT_ASSERT( s.isInside(v100));
+    CPPUNIT_ASSERT(!s.isInside(v110));
+    CPPUNIT_ASSERT( s.isInside(v010));
+    // Quadrant 0 1
+    CPPUNIT_ASSERT(!s.isInside(v210));
+    CPPUNIT_ASSERT( s.isInside(v200));
+    // Quadrant 0 0
+    CPPUNIT_ASSERT(!s.isInside(v220));
+    CPPUNIT_ASSERT( s.isInside(v020));
+    // Quadrant 1 0
+    CPPUNIT_ASSERT(!s.isInside(v120));
+    
+    // z = 1
+    // Quadrant 1 1
+    CPPUNIT_ASSERT( s.isInside(v001));
+    CPPUNIT_ASSERT( s.isInside(v101));
+    CPPUNIT_ASSERT(!s.isInside(v111));
+    CPPUNIT_ASSERT( s.isInside(v011));
+    // Quadrant 0 1
+    CPPUNIT_ASSERT(!s.isInside(v211));
+    CPPUNIT_ASSERT( s.isInside(v201));
+    // Quadrant 0 0
+    CPPUNIT_ASSERT(!s.isInside(v221));
+    CPPUNIT_ASSERT( s.isInside(v021));
+    // Quadrant 1 0
+    CPPUNIT_ASSERT(!s.isInside(v121));
+    
+    // z = 2
+    // Quadrant 1 1
+    CPPUNIT_ASSERT( s.isInside(v002));
+    CPPUNIT_ASSERT( s.isInside(v102));
+    CPPUNIT_ASSERT(!s.isInside(v112));
+    CPPUNIT_ASSERT( s.isInside(v012));
+    // Quadrant 0 1
+    CPPUNIT_ASSERT(!s.isInside(v212));
+    CPPUNIT_ASSERT( s.isInside(v202));
+    // Quadrant 0 0
+    CPPUNIT_ASSERT(!s.isInside(v222));
+    CPPUNIT_ASSERT( s.isInside(v022));
+    // Quadrant 1 0
+    CPPUNIT_ASSERT(!s.isInside(v122));
+
+
+    // More special cylinder
+    s = Cylinder(Vector(0.5, 0.5, 0.0), 0.0, 30.0/180.0*M_PI, 4.0, 1.5);
+
+    CPPUNIT_ASSERT(!s.isInside(v222));
+    CPPUNIT_ASSERT(!s.isInside(v022));
+    CPPUNIT_ASSERT(!s.isInside(v122));
+    CPPUNIT_ASSERT( s.isInside(v202));
+    CPPUNIT_ASSERT( s.isInside(v002));
+    CPPUNIT_ASSERT( s.isInside(v102));
+    CPPUNIT_ASSERT( s.isInside(v212));
+    CPPUNIT_ASSERT( s.isInside(v012));
+    CPPUNIT_ASSERT( s.isInside(v112));
+    
+    CPPUNIT_ASSERT(!s.isInside(v220));
+    CPPUNIT_ASSERT(!s.isInside(v020));
+    CPPUNIT_ASSERT(!s.isInside(v120));
+    CPPUNIT_ASSERT( s.isInside(v200));
+    CPPUNIT_ASSERT( s.isInside(v000));
+    CPPUNIT_ASSERT( s.isInside(v100));
+    CPPUNIT_ASSERT( s.isInside(v210));
+    CPPUNIT_ASSERT( s.isInside(v010));
+    CPPUNIT_ASSERT( s.isInside(v110));
+    
+    CPPUNIT_ASSERT(!s.isInside(v221));
+    CPPUNIT_ASSERT(!s.isInside(v021));
+    CPPUNIT_ASSERT(!s.isInside(v121));
+    CPPUNIT_ASSERT(!s.isInside(v201));
+    CPPUNIT_ASSERT( s.isInside(v001));
+    CPPUNIT_ASSERT( s.isInside(v101));
+    CPPUNIT_ASSERT(!s.isInside(v211));
+    CPPUNIT_ASSERT( s.isInside(v011));
+    CPPUNIT_ASSERT( s.isInside(v111));
+}
 
 void BaseShapesTest::baseShapesTest(){
Index: src/Shapes/unittests/BaseShapesUnitTest.hpp
===================================================================
--- src/Shapes/unittests/BaseShapesUnitTest.hpp	(revision 52575c82d0127ae0f5a1d9fa134d452d2069a4d3)
+++ src/Shapes/unittests/BaseShapesUnitTest.hpp	(revision 0eb8f45f1e1939cbfd3df7516d7961efabb4b05a)
@@ -30,4 +30,5 @@
   CPPUNIT_TEST ( operatorTest );
   CPPUNIT_TEST ( PointsOnSurfaceTest );
+  CPPUNIT_TEST ( cylinderTest );
   CPPUNIT_TEST_SUITE_END();
 
@@ -41,4 +42,5 @@
   void operatorTest();
   void PointsOnSurfaceTest();
+  void cylinderTest();
 
   // a lot of vectors.
