diff --git a/CgBase/CgEnums.h b/CgBase/CgEnums.h
index 5a06a27f7ca8a31ccbe0b27c6a170b1efe2ed831..e4a59aa7a99108684e88d506781caab847dedf4d 100644
--- a/CgBase/CgEnums.h
+++ b/CgBase/CgEnums.h
@@ -32,7 +32,7 @@ namespace Cg{
     CgPickRayEvent                  = 0x0002000,
     // unused, may be changed to whatever     
     CgKdTreeEvent 				    = 0x0004000,
-    CgSomeSpecialEvent4             = 0x0008000,
+    CgShowNormalsEvent	            = 0x0008000,
     CgEventGroup1                   = 0x000f000,
 
     // feel free to add whatever you like
diff --git a/CgEvents/CgShowNormalsEvent.cpp b/CgEvents/CgShowNormalsEvent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..84e5a142e01c5c75fa19d68954c26f81a5a4c097
--- /dev/null
+++ b/CgEvents/CgShowNormalsEvent.cpp
@@ -0,0 +1,30 @@
+#include "CgShowNormalsEvent.h"
+
+CgBaseEvent* CgShowNormalsEvent::clone()
+{
+    return new CgShowNormalsEvent(m_type);
+}
+
+Cg::EventType CgShowNormalsEvent::getType()
+{
+    return m_type;
+}
+
+
+std::ostream& operator<<(std::ostream& os,const CgShowNormalsEvent& e)
+{
+    os << "CgShowNormalsEvent" << " ";
+    return os;
+}
+
+CgShowNormalsEvent::CgShowNormalsEvent(Cg::EventType type)
+{
+    m_type=type;
+}
+
+
+CgShowNormalsEvent::CgShowNormalsEvent()
+{
+    m_type=Cg::CgShowNormalsEvent;
+}
+
diff --git a/CgEvents/CgShowNormalsEvent.h b/CgEvents/CgShowNormalsEvent.h
new file mode 100644
index 0000000000000000000000000000000000000000..908a80889c75d7cad59ae5b7856b68df13c2d9e5
--- /dev/null
+++ b/CgEvents/CgShowNormalsEvent.h
@@ -0,0 +1,26 @@
+#ifndef CG_SHOWNORMALSEVENT
+#define CG_SHOWNORMALSEVENT
+
+#include "../CgBase/CgBaseEvent.h"
+#include "../CgBase/CgEnums.h"
+#include <iostream>
+#include <string>
+
+class CgShowNormalsEvent : public CgBaseEvent
+{
+public:
+    CgShowNormalsEvent();
+    CgShowNormalsEvent(Cg::EventType type);
+    ~CgShowNormalsEvent(){};
+
+    //inherited
+    Cg::EventType  getType();
+    CgBaseEvent* clone();
+
+    // CgShowNormalsEvent
+    friend std::ostream& operator <<(std::ostream& os, const CgShowNormalsEvent& e);
+
+private:
+     Cg::EventType m_type;
+};
+#endif // CG_SHOWNORMALSEVENT
\ No newline at end of file
diff --git a/CgEvents/CgSimplifyEvent.cpp b/CgEvents/CgSimplifyEvent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..84e5a142e01c5c75fa19d68954c26f81a5a4c097
--- /dev/null
+++ b/CgEvents/CgSimplifyEvent.cpp
@@ -0,0 +1,30 @@
+#include "CgShowNormalsEvent.h"
+
+CgBaseEvent* CgShowNormalsEvent::clone()
+{
+    return new CgShowNormalsEvent(m_type);
+}
+
+Cg::EventType CgShowNormalsEvent::getType()
+{
+    return m_type;
+}
+
+
+std::ostream& operator<<(std::ostream& os,const CgShowNormalsEvent& e)
+{
+    os << "CgShowNormalsEvent" << " ";
+    return os;
+}
+
+CgShowNormalsEvent::CgShowNormalsEvent(Cg::EventType type)
+{
+    m_type=type;
+}
+
+
+CgShowNormalsEvent::CgShowNormalsEvent()
+{
+    m_type=Cg::CgShowNormalsEvent;
+}
+
diff --git a/CgEvents/CgSimplifyEvent.h b/CgEvents/CgSimplifyEvent.h
new file mode 100644
index 0000000000000000000000000000000000000000..908a80889c75d7cad59ae5b7856b68df13c2d9e5
--- /dev/null
+++ b/CgEvents/CgSimplifyEvent.h
@@ -0,0 +1,26 @@
+#ifndef CG_SHOWNORMALSEVENT
+#define CG_SHOWNORMALSEVENT
+
+#include "../CgBase/CgBaseEvent.h"
+#include "../CgBase/CgEnums.h"
+#include <iostream>
+#include <string>
+
+class CgShowNormalsEvent : public CgBaseEvent
+{
+public:
+    CgShowNormalsEvent();
+    CgShowNormalsEvent(Cg::EventType type);
+    ~CgShowNormalsEvent(){};
+
+    //inherited
+    Cg::EventType  getType();
+    CgBaseEvent* clone();
+
+    // CgShowNormalsEvent
+    friend std::ostream& operator <<(std::ostream& os, const CgShowNormalsEvent& e);
+
+private:
+     Cg::EventType m_type;
+};
+#endif // CG_SHOWNORMALSEVENT
\ No newline at end of file
diff --git a/CgQtViewer/CgQtGui.cpp b/CgQtViewer/CgQtGui.cpp
index 7bff5da1a8be48570ea9509f00cf81b09778fbd0..8531aabf18570e75e4029eb75fdb6b3dda51eadd 100644
--- a/CgQtViewer/CgQtGui.cpp
+++ b/CgQtViewer/CgQtGui.cpp
@@ -13,6 +13,7 @@
 #include "../CgEvents/CgSplatEvent.h"
 #include "../CgEvents/CgPickRayEvent.h"
 #include "../CgEvents/CgKdTreeEvent.h"
+#include "../CgEvents/CgShowNormalsEvent.h"
 #include "../CgEvents/CgWheelEvent.h"
 
 #include <QSlider>
@@ -164,6 +165,10 @@ void CgQtGui::createKdTreeOptionPanel(QWidget* parent) {
     max_kd_depth_spinbox->setAlignment(Qt::AlignTop);
     max_kd_depth_spinbox->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
 
+    show_normal_colors_button = new QPushButton("show normal colors");
+    connect(show_normal_colors_button, SIGNAL(clicked()), this, SLOT(slotShowNormalsButtonPressed()));
+    tab1_control->addWidget(show_normal_colors_button);
+
     // fill space
     QWidget *filler = new QWidget();
     tab1_control->addWidget(filler);
@@ -228,6 +233,12 @@ void CgQtGui::slotKdDepthSpinboxChanged() {
     m_glRenderWidget->redraw();
 }
 
+void CgQtGui::slotShowNormalsButtonPressed() {
+    CgBaseEvent* e = new CgShowNormalsEvent(Cg::CgShowNormalsEvent);
+    notifyObserver(e);
+    m_glRenderWidget->redraw();
+}
+
 void CgQtGui::slotLoadPointCloudFile() {
     QString file=  QFileDialog::getOpenFileName(this, tr("Open Obj-File"),"",tr("Model Files (*.obj)"));
     CgBaseEvent* e = new CgLoadPointCloudEvent(Cg::CgLoadPointCloudEvent, file.toStdString());
diff --git a/CgQtViewer/CgQtGui.h b/CgQtViewer/CgQtGui.h
index 767406913a19699fd74a1d44b8a8cbeb3a1aa56f..e5a3de507c58d9a67bad0f4a8ad3923881708b46 100644
--- a/CgQtViewer/CgQtGui.h
+++ b/CgQtViewer/CgQtGui.h
@@ -98,10 +98,16 @@ private:
     void createKdTreeOptionPanel(QWidget* panel);
     QSpinBox* max_kd_depth_spinbox;
     QCheckBox* display_kd_tree_checkbox;
+    QPushButton* show_normal_colors_button;
 
     /* additional stuff */
-    void createOptionPanelExample2(QWidget* panel);
-    QButtonGroup* myButtonGroup;
+    void createSimplifyOptionPanel(QWidget* panel);
+    QSpinBox* max_number_of_points_spinbox;
+    QSpinBox* max_diameter_of_cluster_spinbox;
+    QSpinBox* max_variance_of_cluster_spinbox;
+    QButtonGroup* clustering_type_buttongroup;
+    QPushButton* calculate_clustering_button;
+    QPushButton* reset_simplification_button;
 
     bool m_use_spats;
     bool m_show_pickray;
@@ -116,6 +122,7 @@ private slots:
 
     /* kd tree options slot */
     void slotKdDepthSpinboxChanged();
+    void slotShowNormalsButtonPressed();
 
     /* additional stuff*/
     void slotButtonGroupSelectionChanged();
diff --git a/CgSceneGraph/CgPointCloud.cpp b/CgSceneGraph/CgPointCloud.cpp
index d04c0693ed9de697ed2265f3eff62819e4a09e22..629b4caa6f165390f9791f3b17823f5f3c5a5cbe 100644
--- a/CgSceneGraph/CgPointCloud.cpp
+++ b/CgSceneGraph/CgPointCloud.cpp
@@ -82,6 +82,7 @@ void CgPointCloud::init( std::string filename, bool cheat_normals) {
     //for(unsigned int i = 0; i < m_vertices.size(); i++) {
     //  m_vertex_colors[i] = glm::vec3(0.0,1.0,0.0);
     //}
+    resetColors(glm::vec3(0.0, 0.75, 0.0));
 }
 
 void CgPointCloud::buildKdTree(glm::vec3* begin, glm::vec3* end, int depth) {
@@ -165,11 +166,6 @@ void CgPointCloud::estimateNormals() {
     glm::vec3 normal = m_vertex_normals[curr];
     normal = glm::dot(normal, parent_normal) > 0.0 ? normal : -normal;
     m_vertex_normals[curr] = normal;
-    m_vertex_colors[curr] = glm::vec3(
-      (normal.x + 1.0) * .5, 
-      (normal.y + 1.0) * .5, 
-      (normal.z + 1.0) * .5
-    );
 
     // retrieve neighbourhood indices
     auto curr_nh_ind = neighbourhoods[curr];
@@ -400,6 +396,17 @@ void CgPointCloud::resetColors(glm::vec3 color) {
   for(unsigned int i = 0; i < m_vertices.size(); i++) m_vertex_colors[i] = color;
 }
 
+void CgPointCloud::showNormalColors() {
+  for(int i = 0; i < m_vertices.size(); i++) {
+    glm::vec3 normal = m_vertex_normals[i];
+    m_vertex_colors[i] = glm::vec3(
+      (normal.x + 1.0) * .5, 
+      (normal.y + 1.0) * .5, 
+      (normal.z + 1.0) * .5
+    );
+  }
+}
+
 // calculates an arbitrary verctor perpendicular to the given one
 glm::vec3 CgPointCloud::getPerpendicularVector(glm::vec3 arg) {
   if((arg.x == 0.0) && (arg.y == 0.0)) {
diff --git a/CgSceneGraph/CgPointCloud.h b/CgSceneGraph/CgPointCloud.h
index fe5ef5e52b7aa0346150088dda30283e4a4d4b60..b530e4d546cd14ef594aafe62633454cc1a283c9 100644
--- a/CgSceneGraph/CgPointCloud.h
+++ b/CgSceneGraph/CgPointCloud.h
@@ -65,6 +65,7 @@ public:
 
   // change colors of a list of points
   void setColors(std::vector<unsigned int> indices, glm::vec3 color);
+  void showNormalColors();
   void resetColors(glm::vec3 color);
 
   // the center of gravity of the object, for rendering
diff --git a/CgSceneGraph/CgSceneControl.cpp b/CgSceneGraph/CgSceneControl.cpp
index 7c9a79d7bde71f0038a9c8d659b97e1367b897f8..815a1cf6feee1b3248fccde71e22be43967ecb87 100644
--- a/CgSceneGraph/CgSceneControl.cpp
+++ b/CgSceneGraph/CgSceneControl.cpp
@@ -322,6 +322,14 @@ void CgSceneControl::handleEvent(CgBaseEvent* e) {
       m_renderer->redraw();
     }
 
+    // visualize normals by coloring the points according
+    // to their object space normals
+    if(e->getType() & Cg::CgShowNormalsEvent) {
+      if(m_pointcloud != nullptr) m_pointcloud->showNormalColors();
+      m_renderer->init(m_pointcloud);
+      m_renderer->redraw();
+    }
+
     if(e->getType() & Cg::WindowResizeEvent) {
          CgWindowResizeEvent* ev = (CgWindowResizeEvent*)e;
          std::cout << *ev <<std::endl;
diff --git a/ExerciseVC.pro b/ExerciseVC.pro
index e2a40a362350d07db812fe9be302d11013fd2850..0fdf709a4e0ca3a0e0c80bab96c7862a6073cf42 100644
--- a/ExerciseVC.pro
+++ b/ExerciseVC.pro
@@ -9,6 +9,8 @@ SOURCES += main.cpp \
     CgEvents/CgLoadPointCloudEvent.cpp \
     CgEvents/CgPickRayEvent.cpp \
     CgEvents/CgKdTreeEvent.cpp \
+    CgEvents/CgShowNormalsEvent.cpp \
+    CgEvents/CgSimplifyEvent.cpp \
     CgEvents/CgSplatEvent.cpp \
     CgQtViewer/CGQtGLRenderWidget.cpp \
     CgQtViewer/CgQtGui.cpp \
@@ -34,6 +36,8 @@ HEADERS += \
     CgEvents/CgLoadPointCloudEvent.h \
     CgEvents/CgPickRayEvent.h \
     CgEvents/CgKdTreeEvent.h \
+    CgEvents/CgShowNormalsEvent.h \
+    CgEvents/CgSimplifyEvent.h \
     CgEvents/CgSplatEvent.h \
     CgMath/CgDecomposition.h \
     CgMath/Eigen/Core \