diff --git a/base_models/test_split2_unchanged.stl b/base_models/test_split2_unchanged.stl
new file mode 100644
index 0000000000000000000000000000000000000000..a5dce1f755bcf10486e3585c866f34a5832e5bab
--- /dev/null
+++ b/base_models/test_split2_unchanged.stl
@@ -0,0 +1,58 @@
+solid base_models/test_split2_unchanged
+	facet normal 0. 0. -1. 
+		outer loop
+			vertex 2. 0. 0. 
+			vertex 1. -1. 0. 
+			vertex 0.20000000000000001 -1. 0. 
+		endloop
+	endfacet
+	facet normal 0. 0. 1. 
+		outer loop
+			vertex 2. 0. 0. 
+			vertex 0.20000000000000001 -1. 0. 
+			vertex 0.5 -1. 0. 
+		endloop
+	endfacet
+	facet normal -0.55470019622522915 0.83205029433784372 0. 
+		outer loop
+			vertex 2. 0. 0. 
+			vertex 0.5 -1. 0. 
+			vertex 0.5 -1. 1. 
+		endloop
+	endfacet
+	facet normal 0. -0.70710678118654746 -0.70710678118654746 
+		outer loop
+			vertex 2. 0. 0. 
+			vertex 0.5 -1. 1. 
+			vertex 0. -1. 1. 
+		endloop
+	endfacet
+	facet normal -0.57735026918962584 0.57735026918962584 -0.57735026918962584 
+		outer loop
+			vertex 2. 0. 0. 
+			vertex 1. -1. 0. 
+			vertex 0. -1. 1. 
+		endloop
+	endfacet
+	facet normal 0. 1. 0. 
+		outer loop
+			vertex 1. -1. 0. 
+			vertex 0.20000000000000001 -1. 0. 
+			vertex 0. -1. 1. 
+		endloop
+	endfacet
+	facet normal 0. -1. 0. 
+		outer loop
+			vertex 0.20000000000000001 -1. 0. 
+			vertex 0.5 -1. 1. 
+			vertex 0. -1. 1. 
+		endloop
+	endfacet
+	facet normal 0. -1. 0. 
+		outer loop
+			vertex 0.20000000000000001 -1. 0. 
+			vertex 0.5 -1. 0. 
+			vertex 0.5 -1. 1. 
+		endloop
+	endfacet
+endsolid base_models/test_split2_unchanged
\ No newline at end of file
diff --git a/examples.gi b/examples.gi
index 4fe9b97bfedfb2e6dca75322853801b6161557ee..0f359fb3e82df544a84a1d87154bbc7f39e0f4fc 100644
--- a/examples.gi
+++ b/examples.gi
@@ -1789,23 +1789,20 @@ InstallMethod( TestIntersections,
     [],
     function()
         local surf, verticesPositions, pRecord;
-        surf := SimplicialSurfaceByVerticesInFaces( [[4,5,6],[1,2,3],[4,6,7],[5,4,8],[5,6,9]] );
-        verticesPositions :=[[ -1.0000000000,  0.0000000000,  0.0000000000 ],
-                            [ 0.0000000000, 1.0000000000 ,  0.0000000000 ],
-                            [ 1.0000000000, 0.0000000000,  0.0000000000 ],
-                            [ 0.0000000000, 0.300000000, -1.000000000 ],
-                            [ 0.0000000000, 0.8000000000 ,  0.0000000000 ],
-                            [ 0.0000000000, 0.3000000000, 1.0000000000 ],
-                            [ 0.0000000000, -1.0000000000 ,  0.0000000000],
-                            [ 0.0000000000, 1.0000000000, -1.000000000 ],
-                            [ 0.0000000000, 1.000000000, 1.000000000 ],
+        surf := TriangularComplexByVerticesInFaces( [[1,2,6],[1,4,5]]);
+        verticesPositions :=[[ 2.0000000000,  0.0000000000,  0.0000000000 ],
+                            [ 1.0000000000, -1.0000000000 ,  0.0000000000 ],
+                            [ 0.2000000000, -1.5000000000,  0.0000000000 ],
+                            [ 0.3000000000, -1.500000000, 0.500000000 ],
+                            [ 0.3000000000, -1.5000000000 ,  1.0000000000 ],
+                            [ -1.0000000000, -1.000000000, 1.0000000000 ],
                             ];
         
         pRecord := SetVertexCoordinates3D(surf, verticesPositions, rec());
-        DrawSurfaceToSTL(surf,"test_split2",pRecord, true);
+        DrawSurfaceToSTL(surf,"test_split2",pRecord, false);
     end
 );
-
+#Coords := [[[ 2.0000000000,  0.0000000000,  0.0000000000 ],[ 1.0000000000, -1.0000000000 ,  0.0000000000 ],[ -1.0000000000, -1.000000000, 1.0000000000 ]],[[ 2.0000000000,  0.0000000000,  0.0000000000 ],[ 0.5000000000, -1.500000000, 0.000000000 ],[ 0.4000000000, -1.5000000000 ,  1.0000000000 ]]];
 InstallMethod( TestIntersections2,
     [],
     function()
@@ -1827,6 +1824,7 @@ InstallMethod( TestIntersections2,
     end
 );
 
+
 InstallMethod( TestTriang2,
     [],
     function()
diff --git a/htmls/3gs_files.g b/htmls/3gs_files.g
new file mode 100644
index 0000000000000000000000000000000000000000..cce6de6a9a4202958b353ed911f4cbf429bc1161
--- /dev/null
+++ b/htmls/3gs_files.g
@@ -0,0 +1,73 @@
+#3_2
+
+ico := Icosahedron();
+        
+Coord3_2:= [
+                    [  0.9510565160,  0.0000000000,  0.0000000000 ],
+                    [  0.4253254040,  0.8506508085,  0.0000000000 ],
+                    [  0.4253254040,  0.2628655560,  0.8090169940 ],
+                    [ -0.0449027976, -0.0277514551,  0.0854101965 ],
+                    [  0.4253254040, -0.6881909604, -0.4999999998 ],
+                    [  0.4253254040, -0.6881909604,  0.4999999998 ],
+                    [ -0.4253254040,  0.6881909604,  0.4999999998 ],
+                    [ -0.4253254040,  0.6881909604, -0.4999999998 ],
+                    [ -0.4253254040, -0.2628655560, -0.8090169940 ],
+                    [ -0.4253254040, -0.8506508085,  0.0000000000 ],
+                    [  0.0449027976,  0.0277514551, -0.0854101965 ],
+                    [ -0.9510565160,  0.0000000000,  0.0000000000 ],
+                    ];
+pRecord1 := SetVertexCoordinates3D(ico, Coord3_2, rec());
+DrawComplexToJavaScript(ico,"ico_32",pRecord1);
+
+# intersection example 1
+coordinates:=[[0.,0.,1.],[1.5,0.,1],[0.,2.,1.],[0.75,0.5,1.5],[0.75,0.5,0.5],[2,0.5,0.5]];
+
+faces:=[ [ 1, 2, 3 ], [ 4, 5, 6 ]];
+
+t:=TriangularComplexByVerticesInFaces(faces);
+pRecord2 := SetVertexCoordinates3D(t, coordinates, rec());
+
+
+
+DrawComplexToJavaScript(t,"Intersection",pRecord2);
+
+# intersection example 2
+coordinates:=[[0.,0.,1.],[1.,0.,1],[0.,2.,1.],[1.5,0,1],[0.5,1.,1]];
+
+faces:=[ [ 1, 2, 3 ], [ 2, 4, 5]];
+
+t:=TriangularComplexByVerticesInFaces(faces);
+pRecord2 := SetVertexCoordinates3D(t, coordinates, rec());
+
+
+DrawComplexToJavaScript(t,"Intersection2",pRecord2);
+
+
+# ramified example
+
+coordinates:=[[0.,-1.,0.],[0.,1.,0.],[0.5,1.,0.5],[0.5,1.,-0.5],[-0.5,1.,0.5],[-0.5,1.,-0.5]];
+
+faces:=[ [ 1, 2, 3 ], [ 1, 2, 4], [ 1, 2, 5], [ 1, 2, 6]];
+
+t:=TriangularComplexByVerticesInFaces(faces);
+pRecord3 := SetVertexCoordinates3D(t, coordinates, rec());
+SetEdgeColour(t,1,0xFF0000,pRecord3);
+pRecord3:=ActivateLineWidth(t, pRecord3);
+
+
+DrawComplexToJavaScript(t,"ramified1",pRecord3);
+
+# unramified example
+
+coordinates:=[[0.,-1.,-0.1],[0.,1.,-0.1],[0.,-1.,0.1],[0.,1.,0.1],[0.5,1.,0.5],[0.5,1.,-0.5],[-0.5,1.,0.5],[-0.5,1.,-0.5]];
+
+faces:=[ [ 3, 4, 5 ], [ 1, 2, 6], [ 3, 4, 7], [ 1, 2, 8]];
+
+t:=TriangularComplexByVerticesInFaces(faces);
+pRecord3 := SetVertexCoordinates3D(t, coordinates, rec());
+SetEdgeColour(t,1,"0xFF0000",pRecord3);
+SetEdgeColour(t,6,"0xFF0000",pRecord3);
+pRecord3:=ActivateLineWidth(t, pRecord3);
+
+
+DrawComplexToJavaScript(t,"un_ramified1",pRecord3);
diff --git a/htmls/Intersection.html b/htmls/Intersection.html
new file mode 100644
index 0000000000000000000000000000000000000000..dddb0c07e8412ae92db8f1ffa0e0f488807ec9c1
--- /dev/null
+++ b/htmls/Intersection.html
@@ -0,0 +1,761 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="utf-8">
+		<title>SimplicialSurface</title>
+		<style>
+			body { margin: 0; }
+		</style>
+
+
+	</head>
+	<body>
+
+<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>
+
+
+<script type="importmap">
+	{
+		"imports": {
+			"three": "https://unpkg.com/three@0.148.0/build/three.module.js",
+			"three/addons/": "https://unpkg.com/three@0.148.0/examples/jsm/",
+			"gui": "https://unpkg.com/dat.gui@0.7.9/build/dat.gui.module.js"
+		}
+	}
+</script>
+
+
+<script type="module">
+	import * as THREE from 'three';
+	import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
+	import { GUI } from 'gui';
+	import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
+	import { Line2 } from 'three/addons/lines/Line2.js';
+	import { LineMaterial } from 'three/addons/lines/LineMaterial.js';
+	import { LineGeometry } from 'three/addons/lines/LineGeometry.js';
+
+	//start scene and camera
+	const scene = new THREE.Scene();
+	const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 100 );
+
+	const renderer = new THREE.WebGLRenderer({ antialias: true });
+	renderer.setSize( window.innerWidth, window.innerHeight );
+	document.body.appendChild( renderer.domElement );
+
+	//Lights
+	const skyColor = 0xFFFFFF;
+	const skyIntensity = 0.3;
+	const skyLight = new THREE.AmbientLight(skyColor, skyIntensity);
+	scene.add(skyLight);
+
+	const color = 0xFFFFFF;
+	const intensity = 1;
+	const light = new THREE.PointLight(color, intensity);
+	light.position.set(0, 3, -5);
+	scene.add(light);
+
+	//create groups to add everything to
+	const meshRoot = new THREE.Group();
+	const wireRoot = new THREE.Group();
+	const vertexRoot = new THREE.Group();
+	const vertexlabelRoot = new THREE.Group();
+	const edgeRoot = new THREE.Group();
+	const ringRoot = new THREE.Group();
+	const normalsRoot = new THREE.Group();
+	const normalMeshRoot = new THREE.Group();
+
+	//parameters for the controls on the top right
+	var guiParameters = new function() { 
+		this.speedX = 0.0; 
+		this.speedY = 0.0; 
+		this.speedZ = 0.0;
+		this.transparency = 1;
+		this.edgeVisibility = false;
+		this.edgeWidth = 0.2;
+
+		this.vertexVisibility = true;
+		this.vertexlabelVisibility = false;
+		this.vertexSize = 1;
+		this.planeX = 0.0;
+		this.minX = -1.5;
+		this.maxX = 1.5;
+		this.planeXactive = false;
+		this.planeY = 0.0;
+		this.minY = -1.5;
+
+		this.maxY = 1.5;
+		this.planeYactive = false;
+		this.planeZ = 0.0;
+		this.minZ = -1.5;
+		this.maxZ = 1.5;
+		this.planeZactive = false;
+		this.normalsMaterial = false;
+		this.circleVisibility = false;
+		this.circleWidth = 0.005;
+		this.normalsVisibility = false;
+		this.normalsLength = 1;
+	} ;
+
+	//generate the plane for intersections
+	const planeX = new THREE.Plane( new THREE.Vector3( -1, 0, 0 ), guiParameters.planeX );
+	const planeY = new THREE.Plane( new THREE.Vector3( 0, -1, 0 ), guiParameters.planeY );
+	const planeZ = new THREE.Plane( new THREE.Vector3( 0, 0, -1 ), guiParameters.planeZ );
+
+	// the array which ones are currently active
+	var activePlanes = [];
+
+	//rederer for lables
+	const labelRenderer = new CSS2DRenderer();
+	labelRenderer.setSize( window.innerWidth, window.innerHeight );
+	labelRenderer.domElement.style.position = 'absolute';
+	labelRenderer.domElement.style.top = '0px';
+	document.body.appendChild( labelRenderer.domElement );
+	
+	//controls for mouse 
+	const controls = new OrbitControls( camera, labelRenderer.domElement );
+
+	//controls in the top right corner
+	var gui = new GUI();
+
+	const animationFolder = gui.addFolder("Animations");
+	animationFolder.add(guiParameters, 'speedX', 0, 5);
+	animationFolder.add(guiParameters, 'speedY', 0, 5);
+	animationFolder.add(guiParameters, 'speedZ', 0, 5);
+	animationFolder.open();
+
+	const controlFolder = gui.addFolder("Controls");
+	controlFolder.add(guiParameters, "transparency", 0, 1);
+	controlFolder.add(guiParameters, "edgeVisibility");
+	var edgeWidthGUI = controlFolder.add(guiParameters, "edgeWidth", 0.01, 2);
+	controlFolder.add(guiParameters, "vertexVisibility");
+	controlFolder.add(guiParameters, "vertexlabelVisibility");
+	controlFolder.add(guiParameters, "vertexSize", 0.1, 3);
+	controlFolder.add(guiParameters, "normalsMaterial");
+	controlFolder.add(guiParameters, "circleVisibility");
+	controlFolder.add(guiParameters, "circleWidth", 0.0001, 0.1);
+	controlFolder.add(guiParameters, "normalsVisibility");
+	controlFolder.add(guiParameters, "normalsLength", 0, 2);
+	controlFolder.open();
+
+	//generate a sphere geometry for the vertices
+	const sphereGeometry = new THREE.SphereGeometry( 0.02, 32, 16 );
+	sphereGeometry.transparent = guiParameters.vertexVisibility;
+	
+	//functions for later calculations
+
+	function calulateIncenter(A, B, C){
+		//we follow the math and variable names from here: https://math.stackexchange.com/questions/740111/incenter-of-triangle-in-3d
+		var a = Math.sqrt((B[0]-C[0])**2 + (B[1]-C[1])**2 + (B[2]-C[2])**2);
+		var b = Math.sqrt((C[0]-A[0])**2 + (C[1]-A[1])**2 + (C[2]-A[2])**2);
+		var c = Math.sqrt((A[0]-B[0])**2 + (A[1]-B[1])**2 + (A[2]-B[2])**2);
+
+		var res = [];
+		res[0] = a/(a+b+c)*A[0] + b/(a+b+c)*B[0] + c/(a+b+c)*C[0];
+		res[1] = a/(a+b+c)*A[1] + b/(a+b+c)*B[1] + c/(a+b+c)*C[1];
+		res[2] = a/(a+b+c)*A[2] + b/(a+b+c)*B[2] + c/(a+b+c)*C[2];
+
+		return res;
+	}
+
+	function calulateInradius(A, B, C){
+		var a = Math.sqrt((B[0]-C[0])**2 + (B[1]-C[1])**2 + (B[2]-C[2])**2);
+		var b = Math.sqrt((C[0]-A[0])**2 + (C[1]-A[1])**2 + (C[2]-A[2])**2);
+		var c = Math.sqrt((A[0]-B[0])**2 + (A[1]-B[1])**2 + (A[2]-B[2])**2);
+
+		var s = (a+b+c)/2;
+		var inradius = Math.sqrt(((s-a)*(s-b)*(s-c)) / s );
+
+		return inradius;
+	}
+
+	// --- start of generated output --- //
+
+	// preperations for parameterized vertex coordinates 
+	const vertexParametriziation = false;
+	// generate the faces color by color 
+	const geometry1 = new THREE.BufferGeometry();
+	function setVertices1(){
+		var vertices1 = new Float32Array( [
+				0.,0.,1.,
+			1.5,0.,1,
+			0.,2.,1.,
+
+			0.75,0.5,1.5,
+			0.75,0.5,0.5,
+			2,0.5,0.5,
+
+					] ); 
+
+		return vertices1; 
+	}
+
+	geometry1.setAttribute( 'position', new THREE.BufferAttribute( setVertices1(), 3 ) );
+
+	// generate materials in the given color and normals material for the faces 
+
+    const materialNormal1 = new THREE.MeshNormalMaterial({
+        flatShading: true,
+    });
+    materialNormal1.transparent = true;
+    materialNormal1.side = THREE.DoubleSide;
+        
+    const material1 = new THREE.MeshPhongMaterial({
+        color: 0x049EF4,
+        flatShading: true,
+    });
+    material1.transparent = true;
+    material1.side = THREE.DoubleSide;
+        
+	// generate meshes for the faces from the materials with the vertex coordinates from before 
+
+    const mesh1 = new THREE.Mesh( geometry1, material1 );
+    mesh1.castShadow = true;                         
+    mesh1.receiveShadow = true;                      
+                                
+    meshRoot.add(mesh1);
+        
+    const meshNormal1 = new THREE.Mesh( geometry1, materialNormal1 );
+    mesh1.castShadow = true;                         
+    mesh1.receiveShadow = true;                      
+                                
+    normalMeshRoot.add(meshNormal1);
+        
+	// generate the edges grouped by color
+		controlFolder.remove(edgeWidthGUI);
+
+    const edgeMaterial1 = new THREE.LineBasicMaterial( {
+        color: 0x000000,
+        linewidth: 3.,
+    } );
+        
+	function getEdges1(){
+		const edges1 = new Float32Array( [
+			0.,0.,1.,
+			1.5,0.,1,
+
+			0.,0.,1.,
+			0.,2.,1.,
+
+			1.5,0.,1,
+			0.,2.,1.,
+
+			0.75,0.5,1.5,
+			0.75,0.5,0.5,
+
+			0.75,0.5,1.5,
+			2,0.5,0.5,
+
+			0.75,0.5,0.5,
+			2,0.5,0.5,
+
+		]);
+		return edges1;
+	}
+
+
+	// generate geometries and lines for the edges 
+
+    const edgeGeometry1 = new THREE.BufferGeometry();
+    edgeGeometry1.setAttribute( 'position', new THREE.BufferAttribute( getEdges1(), 3 ) );
+
+    const edgeLine1 = new THREE.LineSegments( edgeGeometry1, edgeMaterial1 );
+    edgeRoot.add(edgeLine1);
+        
+	// update function to be called every frame 
+	// generate labels and spheres for the vertices
+
+
+	function getVertex1(){
+		return [0.,0.,1.,];
+	}
+	const sphereMaterial1 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere1 = new THREE.Mesh( sphereGeometry, sphereMaterial1 );
+	vertexRoot.add(sphere1);
+	sphere1.position.set(getVertex1()[0],getVertex1()[1],getVertex1()[2]);
+
+    const lableDiv1 = document.createElement( 'div' );
+    lableDiv1.className = 'label';
+    lableDiv1.textContent = '1';
+    lableDiv1.style.marginTop = '-1em';
+
+    const vertexLabel1 = new CSS2DObject( lableDiv1 );
+    vertexLabel1.position.set(getVertex1()[0],getVertex1()[1],getVertex1()[2]);
+    vertexlabelRoot.add( vertexLabel1 );
+            
+            
+
+	function getVertex2(){
+		return [1.5,0.,1,];
+	}
+	const sphereMaterial2 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere2 = new THREE.Mesh( sphereGeometry, sphereMaterial2 );
+	vertexRoot.add(sphere2);
+	sphere2.position.set(getVertex2()[0],getVertex2()[1],getVertex2()[2]);
+
+    const lableDiv2 = document.createElement( 'div' );
+    lableDiv2.className = 'label';
+    lableDiv2.textContent = '2';
+    lableDiv2.style.marginTop = '-1em';
+
+    const vertexLabel2 = new CSS2DObject( lableDiv2 );
+    vertexLabel2.position.set(getVertex2()[0],getVertex2()[1],getVertex2()[2]);
+    vertexlabelRoot.add( vertexLabel2 );
+            
+            
+
+	function getVertex3(){
+		return [0.,2.,1.,];
+	}
+	const sphereMaterial3 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere3 = new THREE.Mesh( sphereGeometry, sphereMaterial3 );
+	vertexRoot.add(sphere3);
+	sphere3.position.set(getVertex3()[0],getVertex3()[1],getVertex3()[2]);
+
+    const lableDiv3 = document.createElement( 'div' );
+    lableDiv3.className = 'label';
+    lableDiv3.textContent = '3';
+    lableDiv3.style.marginTop = '-1em';
+
+    const vertexLabel3 = new CSS2DObject( lableDiv3 );
+    vertexLabel3.position.set(getVertex3()[0],getVertex3()[1],getVertex3()[2]);
+    vertexlabelRoot.add( vertexLabel3 );
+            
+            
+
+	function getVertex4(){
+		return [0.75,0.5,1.5,];
+	}
+	const sphereMaterial4 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere4 = new THREE.Mesh( sphereGeometry, sphereMaterial4 );
+	vertexRoot.add(sphere4);
+	sphere4.position.set(getVertex4()[0],getVertex4()[1],getVertex4()[2]);
+
+    const lableDiv4 = document.createElement( 'div' );
+    lableDiv4.className = 'label';
+    lableDiv4.textContent = '4';
+    lableDiv4.style.marginTop = '-1em';
+
+    const vertexLabel4 = new CSS2DObject( lableDiv4 );
+    vertexLabel4.position.set(getVertex4()[0],getVertex4()[1],getVertex4()[2]);
+    vertexlabelRoot.add( vertexLabel4 );
+            
+            
+
+	function getVertex5(){
+		return [0.75,0.5,0.5,];
+	}
+	const sphereMaterial5 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere5 = new THREE.Mesh( sphereGeometry, sphereMaterial5 );
+	vertexRoot.add(sphere5);
+	sphere5.position.set(getVertex5()[0],getVertex5()[1],getVertex5()[2]);
+
+    const lableDiv5 = document.createElement( 'div' );
+    lableDiv5.className = 'label';
+    lableDiv5.textContent = '5';
+    lableDiv5.style.marginTop = '-1em';
+
+    const vertexLabel5 = new CSS2DObject( lableDiv5 );
+    vertexLabel5.position.set(getVertex5()[0],getVertex5()[1],getVertex5()[2]);
+    vertexlabelRoot.add( vertexLabel5 );
+            
+            
+
+	function getVertex6(){
+		return [2,0.5,0.5,];
+	}
+	const sphereMaterial6 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere6 = new THREE.Mesh( sphereGeometry, sphereMaterial6 );
+	vertexRoot.add(sphere6);
+	sphere6.position.set(getVertex6()[0],getVertex6()[1],getVertex6()[2]);
+
+    const lableDiv6 = document.createElement( 'div' );
+    lableDiv6.className = 'label';
+    lableDiv6.textContent = '6';
+    lableDiv6.style.marginTop = '-1em';
+
+    const vertexLabel6 = new CSS2DObject( lableDiv6 );
+    vertexLabel6.position.set(getVertex6()[0],getVertex6()[1],getVertex6()[2]);
+    vertexlabelRoot.add( vertexLabel6 );
+            
+            	// generate the rings for the incircles 
+
+	var inradius1 = calulateInradius(getVertex1(), getVertex2(), getVertex3());
+	var incenter1 = calulateIncenter(getVertex1(), getVertex2(), getVertex3());
+	var ringGeometry1 = new THREE.RingGeometry((inradius1 - 0.005),inradius1, 32);
+	const ringMaterial1 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh1 = new THREE.Mesh(ringGeometry1, ringMaterial1);
+
+	function setCircleRotation1(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.,0.,1.],[ 1.5,0.,1],[0.,2.,1.]);
+
+        ringMesh1.position.setX(incenter[0]);
+        ringMesh1.position.setY(incenter[1]);
+        ringMesh1.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex1(), getVertex2(), getVertex3());
+        var relRadius = inradius/inradius1;
+
+        ringMesh1.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A1 = new THREE.Vector3(0.,0.,1.);
+        const B1 = new THREE.Vector3(1.5,0.,1);
+        const C1 = new THREE.Vector3(0.,2.,1.);
+
+        const normalVec1 = new THREE.Vector3();
+        normalVec1.crossVectors(B1.sub(A1), C1.sub(A1));
+        normalVec1.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal1 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation1 = new THREE.Quaternion();
+        quaternionRotation1.setFromUnitVectors(initialNormal1, normalVec1);
+
+        ringMesh1.setRotationFromQuaternion(quaternionRotation1);
+
+        return quaternionRotation1;
+    }
+
+    ringRoot.add(ringMesh1);
+            
+	var inradius2 = calulateInradius(getVertex4(), getVertex5(), getVertex6());
+	var incenter2 = calulateIncenter(getVertex4(), getVertex5(), getVertex6());
+	var ringGeometry2 = new THREE.RingGeometry((inradius2 - 0.005),inradius2, 32);
+	const ringMaterial2 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh2 = new THREE.Mesh(ringGeometry2, ringMaterial2);
+
+	function setCircleRotation2(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.75,0.5,1.5],[ 0.75,0.5,0.5],[2,0.5,0.5]);
+
+        ringMesh2.position.setX(incenter[0]);
+        ringMesh2.position.setY(incenter[1]);
+        ringMesh2.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex4(), getVertex5(), getVertex6());
+        var relRadius = inradius/inradius2;
+
+        ringMesh2.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A2 = new THREE.Vector3(0.75,0.5,1.5);
+        const B2 = new THREE.Vector3(0.75,0.5,0.5);
+        const C2 = new THREE.Vector3(2,0.5,0.5);
+
+        const normalVec2 = new THREE.Vector3();
+        normalVec2.crossVectors(B2.sub(A2), C2.sub(A2));
+        normalVec2.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal2 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation2 = new THREE.Quaternion();
+        quaternionRotation2.setFromUnitVectors(initialNormal2, normalVec2);
+
+        ringMesh2.setRotationFromQuaternion(quaternionRotation2);
+
+        return quaternionRotation2;
+    }
+
+    ringRoot.add(ringMesh2);
+            	// function to update the circles every frame 
+	function updateCircles(){
+		setCircleRotation1();
+		setCircleRotation2();
+	}
+
+	// needs to be called once to be initialized 
+	updateCircles();
+
+	// function to update the circles width, that is called every frame even if the surface is not parameterized 
+	function updateCircleWidth(){
+		ringGeometry1.dispose();
+		ringGeometry1 = new THREE.RingGeometry((inradius1 - guiParameters.circleWidth),inradius1, 32);
+		ringMesh1.geometry = ringGeometry1; 
+		ringGeometry2.dispose();
+		ringGeometry2 = new THREE.RingGeometry((inradius2 - guiParameters.circleWidth),inradius2, 32);
+		ringMesh2.geometry = ringGeometry2; 
+	}
+
+	updateCircleWidth();
+
+	// generate the normals trough the incenter orthogonal to the face 
+	// getNormalsVectors generates the coordinates for the current values of the parameterized surface 
+	function getNormalsVectors(){
+		var vector1;
+		var vector2;
+
+		var normals = [];
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (1.5)-(0.);
+		vector1[1] = (0.)-(0.);
+		vector1[2] = (1)-(1.);
+
+		vector2[0] = (0.)-(0.);
+		vector2[1] = (2.)-(0.);
+		vector2[2] = (1.)-(1.);
+
+		var incenter = calulateIncenter([0.,0.,1.],[ 1.5,0.,1],[0.,2.,1.]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.75)-(0.75);
+		vector1[1] = (0.5)-(0.5);
+		vector1[2] = (0.5)-(1.5);
+
+		vector2[0] = (2)-(0.75);
+		vector2[1] = (0.5)-(0.5);
+		vector2[2] = (0.5)-(1.5);
+
+		var incenter = calulateIncenter([0.75,0.5,1.5],[ 0.75,0.5,0.5],[2,0.5,0.5]);
+		normals.push([vector1, vector2, incenter]);
+
+	return normals;
+	}
+	// getNormalsCoordinates calculates the right coordinates for the ortogonality and fitting values from the gui 
+	function getNormalsCoordinates(){
+		var res = [];
+		var normals = getNormalsVectors(); 
+        for(var i = 0; i < normals.length; i++){
+            var plus = [];
+            var minus = [];
+
+            minus[0] = normals[i][2][0] - (1/2)*guiParameters.normalsLength*(normals[i][0][1]*normals[i][1][2] - normals[i][0][2]*normals[i][1][1]);
+            minus[1] = normals[i][2][1] - (1/2)*guiParameters.normalsLength*(normals[i][0][2]*normals[i][1][0] - normals[i][0][0]*normals[i][1][2]);
+            minus[2] = normals[i][2][2] - (1/2)*guiParameters.normalsLength*(normals[i][0][0]*normals[i][1][1] - normals[i][0][1]*normals[i][1][0]);
+
+            plus[0] = normals[i][2][0] + (1/2)*guiParameters.normalsLength*(normals[i][0][1]*normals[i][1][2] - normals[i][0][2]*normals[i][1][1]);
+            plus[1] = normals[i][2][1] + (1/2)*guiParameters.normalsLength*(normals[i][0][2]*normals[i][1][0] - normals[i][0][0]*normals[i][1][2]);
+            plus[2] = normals[i][2][2] + (1/2)*guiParameters.normalsLength*(normals[i][0][0]*normals[i][1][1] - normals[i][0][1]*normals[i][1][0]);
+
+            res.push(minus[0]);
+            res.push(minus[1]);
+            res.push(minus[2]);
+            res.push(plus[0]);
+            res.push(plus[1]);
+            res.push(plus[2]);
+        }
+        res = Float32Array.from(res);
+
+    
+		return res;
+	}
+
+
+    const normalsMaterial = new THREE.LineBasicMaterial( {
+        color: 0x000000,
+    } );
+    
+    const normalsGeometry = new THREE.BufferGeometry();
+    normalsGeometry.setAttribute( 'position', new THREE.BufferAttribute( getNormalsCoordinates(), 3 ) );
+    var normalsLine = new THREE.LineSegments( normalsGeometry, normalsMaterial );
+
+    function updateNormals(){
+        normalsGeometry.setAttribute( 'position', new THREE.BufferAttribute( getNormalsCoordinates(), 3 ) );
+        normalsLine = new THREE.LineSegments( normalsGeometry, normalsMaterial );
+    }
+    
+    normalsRoot.add(normalsLine);
+
+    
+	// generate automatic ranges for the intersections if the surface is not parameterized 
+	guiParameters.maxX = 2.;
+	guiParameters.maxY = 2.;
+	guiParameters.maxZ = 1.5;
+	guiParameters.minX = 0.;
+	guiParameters.minY = 0.;
+	guiParameters.minZ = 0.;
+
+	guiParameters.planeX = 1.;
+	guiParameters.planeY = 1.;
+	guiParameters.planeZ = 0.75;
+	// --- end of generated output --- //
+
+    const planeFolder = gui.addFolder("Intersection Planes");
+    planeFolder.add(guiParameters, 'planeXactive');
+    planeFolder.add(guiParameters, 'planeX', guiParameters.minX*1.1, guiParameters.maxX*1.1);
+    planeFolder.add(guiParameters, 'planeYactive');
+    planeFolder.add(guiParameters, 'planeY', guiParameters.minY*1.1, guiParameters.maxY*1.1);
+    planeFolder.add(guiParameters, 'planeZactive');
+    planeFolder.add(guiParameters, 'planeZ', guiParameters.minZ*1.1, guiParameters.maxZ*1.1);
+    
+    camera.position.z = Math.max((1.5)*guiParameters.minZ, 1)
+    camera.lookAt(0,0,-1);
+
+    scene.background = new THREE.Color( 'white' );
+
+    // add both roots to the scene
+    scene.add( meshRoot );
+    scene.add( wireRoot );
+    scene.add( vertexRoot );
+    scene.add( vertexlabelRoot );
+    scene.add( edgeRoot );
+    scene.add( ringRoot );
+    scene.add( normalsRoot );
+    scene.add( normalMeshRoot );
+
+    //presave some current gui parameters to only update if they change
+    var currentCircleWidth = guiParameters.circleWidth;
+
+    function animate() {
+        requestAnimationFrame( animate );
+        meshRoot.rotation.x += guiParameters.speedX/100;
+        meshRoot.rotation.y += guiParameters.speedY/100;
+        meshRoot.rotation.z += guiParameters.speedZ/100;
+
+        wireRoot.rotation.x += guiParameters.speedX/100;
+        wireRoot.rotation.y += guiParameters.speedY/100;
+        wireRoot.rotation.z += guiParameters.speedZ/100;
+
+        vertexRoot.rotation.x += guiParameters.speedX/100;
+        vertexRoot.rotation.y += guiParameters.speedY/100;
+        vertexRoot.rotation.z += guiParameters.speedZ/100;
+
+        vertexlabelRoot.rotation.x += guiParameters.speedX/100;
+        vertexlabelRoot.rotation.y += guiParameters.speedY/100;
+        vertexlabelRoot.rotation.z += guiParameters.speedZ/100;
+
+        edgeRoot.rotation.x += guiParameters.speedX/100;
+        edgeRoot.rotation.y += guiParameters.speedY/100;
+        edgeRoot.rotation.z += guiParameters.speedZ/100;
+
+        ringRoot.rotation.x += guiParameters.speedX/100;
+        ringRoot.rotation.y += guiParameters.speedY/100;
+        ringRoot.rotation.z += guiParameters.speedZ/100;
+
+        normalsRoot.rotation.x += guiParameters.speedX/100;
+        normalsRoot.rotation.y += guiParameters.speedY/100;
+        normalsRoot.rotation.z += guiParameters.speedZ/100;
+
+        normalMeshRoot.rotation.x += guiParameters.speedX/100;
+        normalMeshRoot.rotation.y += guiParameters.speedY/100;
+        normalMeshRoot.rotation.z += guiParameters.speedZ/100;
+
+        //update the light when the camera moves (with orbitcontrols)
+        light.position.set(camera.position.x, camera.position.y, camera.position.z);
+
+        planeX.constant = guiParameters.planeX;
+        planeY.constant = guiParameters.planeY;
+        planeZ.constant = guiParameters.planeZ;
+
+        activePlanes = [];
+        if(guiParameters.planeXactive){
+            activePlanes.push(planeX);
+        }
+        if(guiParameters.planeYactive){
+            activePlanes.push(planeY);
+        }
+        if(guiParameters.planeZactive){
+            activePlanes.push(planeZ);
+        }
+
+        if(vertexParametriziation){
+            updateFaceCoordinates();
+            if(guiParameters.edgeVisibility){
+                updateEdgeCoordinates();
+            }
+            if(guiParameters.vertexlabelVisibility || guiParameters.vertexVisibility){
+                updateVertexCoordinates();
+            }
+            if(guiParameters.circleVisibility){
+                updateCircles();
+            }
+        }                
+
+        //update stuff that changes from the gui
+        meshRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.opacity = guiParameters.transparency;
+                node.material.clippingPlanes = activePlanes;
+                if(guiParameters.normalsMaterial){
+                    node.material.opacity = 0;
+                }
+            }
+        } );
+
+        normalMeshRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.opacity = guiParameters.transparency;
+                node.material.clippingPlanes = activePlanes;
+                if(!guiParameters.normalsMaterial){
+                    node.material.opacity = 0;
+                }
+            }
+        } );
+
+        edgeRoot.traverse( function( node ) {
+            if ( node instanceof Line2 ) {
+                node.material.visible = guiParameters.edgeVisibility;
+                node.material.linewidth = guiParameters.edgeWidth/100;
+            }
+            if ( node instanceof THREE.LineSegments ) {
+                node.material.visible = guiParameters.edgeVisibility;
+            }
+        } );
+
+        vertexRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.visible = guiParameters.vertexVisibility;
+                node.scale.setScalar(guiParameters.vertexSize);
+            }
+        } );
+
+        vertexlabelRoot.traverse( function( node ) {
+            if( node instanceof CSS2DObject) {
+                node.visible = guiParameters.vertexlabelVisibility;
+            }
+        } );
+
+        ringRoot.traverse( function( node ) {
+            if( node instanceof THREE.Mesh) {
+                node.visible = guiParameters.circleVisibility;
+            }
+        } );
+
+        normalsRoot.traverse( function( node ) {
+            if( node instanceof THREE.LineSegments) {
+                node.visible = guiParameters.normalsVisibility;
+            }
+        } );
+
+        // update the circle width
+        if(guiParameters.circleVisibility && currentCircleWidth != guiParameters.circleWidth){
+            updateCircleWidth();
+            currentCircleWidth = guiParameters.circleWidth;
+        }
+
+        //update the normals length 
+        if(guiParameters.normalsVisibility){
+            updateNormals();
+        }
+
+        controls.update();
+
+        renderer.localClippingEnabled = true;
+
+        renderer.render( scene, camera );
+        labelRenderer.render( scene, camera );
+    }
+    animate();
+
+    //resize of window size changes
+    window.addEventListener( 'resize', onWindowResize );
+    function onWindowResize() {
+        camera.aspect = window.innerWidth / window.innerHeight;
+        camera.updateProjectionMatrix();
+
+        renderer.setSize( window.innerWidth, window.innerHeight );
+        labelRenderer.setSize( window.innerWidth, window.innerHeight );
+    }
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/htmls/Intersection2.html b/htmls/Intersection2.html
new file mode 100644
index 0000000000000000000000000000000000000000..5ba3e2a2813feb3df8e9529117c1da0543bce8bf
--- /dev/null
+++ b/htmls/Intersection2.html
@@ -0,0 +1,742 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="utf-8">
+		<title>SimplicialSurface</title>
+		<style>
+			body { margin: 0; }
+		</style>
+
+
+	</head>
+	<body>
+
+<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>
+
+
+<script type="importmap">
+	{
+		"imports": {
+			"three": "https://unpkg.com/three@0.148.0/build/three.module.js",
+			"three/addons/": "https://unpkg.com/three@0.148.0/examples/jsm/",
+			"gui": "https://unpkg.com/dat.gui@0.7.9/build/dat.gui.module.js"
+		}
+	}
+</script>
+
+
+<script type="module">
+	import * as THREE from 'three';
+	import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
+	import { GUI } from 'gui';
+	import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
+	import { Line2 } from 'three/addons/lines/Line2.js';
+	import { LineMaterial } from 'three/addons/lines/LineMaterial.js';
+	import { LineGeometry } from 'three/addons/lines/LineGeometry.js';
+
+	//start scene and camera
+	const scene = new THREE.Scene();
+	const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 100 );
+
+	const renderer = new THREE.WebGLRenderer({ antialias: true });
+	renderer.setSize( window.innerWidth, window.innerHeight );
+	document.body.appendChild( renderer.domElement );
+
+	//Lights
+	const skyColor = 0xFFFFFF;
+	const skyIntensity = 0.3;
+	const skyLight = new THREE.AmbientLight(skyColor, skyIntensity);
+	scene.add(skyLight);
+
+	const color = 0xFFFFFF;
+	const intensity = 1;
+	const light = new THREE.PointLight(color, intensity);
+	light.position.set(0, 3, -5);
+	scene.add(light);
+
+	//create groups to add everything to
+	const meshRoot = new THREE.Group();
+	const wireRoot = new THREE.Group();
+	const vertexRoot = new THREE.Group();
+	const vertexlabelRoot = new THREE.Group();
+	const edgeRoot = new THREE.Group();
+	const ringRoot = new THREE.Group();
+	const normalsRoot = new THREE.Group();
+	const normalMeshRoot = new THREE.Group();
+
+	//parameters for the controls on the top right
+	var guiParameters = new function() { 
+		this.speedX = 0.0; 
+		this.speedY = 0.0; 
+		this.speedZ = 0.0;
+		this.transparency = 1;
+		this.edgeVisibility = false;
+		this.edgeWidth = 0.2;
+
+		this.vertexVisibility = true;
+		this.vertexlabelVisibility = false;
+		this.vertexSize = 1;
+		this.planeX = 0.0;
+		this.minX = -1.5;
+		this.maxX = 1.5;
+		this.planeXactive = false;
+		this.planeY = 0.0;
+		this.minY = -1.5;
+
+		this.maxY = 1.5;
+		this.planeYactive = false;
+		this.planeZ = 0.0;
+		this.minZ = -1.5;
+		this.maxZ = 1.5;
+		this.planeZactive = false;
+		this.normalsMaterial = false;
+		this.circleVisibility = false;
+		this.circleWidth = 0.005;
+		this.normalsVisibility = false;
+		this.normalsLength = 1;
+	} ;
+
+	//generate the plane for intersections
+	const planeX = new THREE.Plane( new THREE.Vector3( -1, 0, 0 ), guiParameters.planeX );
+	const planeY = new THREE.Plane( new THREE.Vector3( 0, -1, 0 ), guiParameters.planeY );
+	const planeZ = new THREE.Plane( new THREE.Vector3( 0, 0, -1 ), guiParameters.planeZ );
+
+	// the array which ones are currently active
+	var activePlanes = [];
+
+	//rederer for lables
+	const labelRenderer = new CSS2DRenderer();
+	labelRenderer.setSize( window.innerWidth, window.innerHeight );
+	labelRenderer.domElement.style.position = 'absolute';
+	labelRenderer.domElement.style.top = '0px';
+	document.body.appendChild( labelRenderer.domElement );
+	
+	//controls for mouse 
+	const controls = new OrbitControls( camera, labelRenderer.domElement );
+
+	//controls in the top right corner
+	var gui = new GUI();
+
+	const animationFolder = gui.addFolder("Animations");
+	animationFolder.add(guiParameters, 'speedX', 0, 5);
+	animationFolder.add(guiParameters, 'speedY', 0, 5);
+	animationFolder.add(guiParameters, 'speedZ', 0, 5);
+	animationFolder.open();
+
+	const controlFolder = gui.addFolder("Controls");
+	controlFolder.add(guiParameters, "transparency", 0, 1);
+	controlFolder.add(guiParameters, "edgeVisibility");
+	var edgeWidthGUI = controlFolder.add(guiParameters, "edgeWidth", 0.01, 2);
+	controlFolder.add(guiParameters, "vertexVisibility");
+	controlFolder.add(guiParameters, "vertexlabelVisibility");
+	controlFolder.add(guiParameters, "vertexSize", 0.1, 3);
+	controlFolder.add(guiParameters, "normalsMaterial");
+	controlFolder.add(guiParameters, "circleVisibility");
+	controlFolder.add(guiParameters, "circleWidth", 0.0001, 0.1);
+	controlFolder.add(guiParameters, "normalsVisibility");
+	controlFolder.add(guiParameters, "normalsLength", 0, 2);
+	controlFolder.open();
+
+	//generate a sphere geometry for the vertices
+	const sphereGeometry = new THREE.SphereGeometry( 0.02, 32, 16 );
+	sphereGeometry.transparent = guiParameters.vertexVisibility;
+	
+	//functions for later calculations
+
+	function calulateIncenter(A, B, C){
+		//we follow the math and variable names from here: https://math.stackexchange.com/questions/740111/incenter-of-triangle-in-3d
+		var a = Math.sqrt((B[0]-C[0])**2 + (B[1]-C[1])**2 + (B[2]-C[2])**2);
+		var b = Math.sqrt((C[0]-A[0])**2 + (C[1]-A[1])**2 + (C[2]-A[2])**2);
+		var c = Math.sqrt((A[0]-B[0])**2 + (A[1]-B[1])**2 + (A[2]-B[2])**2);
+
+		var res = [];
+		res[0] = a/(a+b+c)*A[0] + b/(a+b+c)*B[0] + c/(a+b+c)*C[0];
+		res[1] = a/(a+b+c)*A[1] + b/(a+b+c)*B[1] + c/(a+b+c)*C[1];
+		res[2] = a/(a+b+c)*A[2] + b/(a+b+c)*B[2] + c/(a+b+c)*C[2];
+
+		return res;
+	}
+
+	function calulateInradius(A, B, C){
+		var a = Math.sqrt((B[0]-C[0])**2 + (B[1]-C[1])**2 + (B[2]-C[2])**2);
+		var b = Math.sqrt((C[0]-A[0])**2 + (C[1]-A[1])**2 + (C[2]-A[2])**2);
+		var c = Math.sqrt((A[0]-B[0])**2 + (A[1]-B[1])**2 + (A[2]-B[2])**2);
+
+		var s = (a+b+c)/2;
+		var inradius = Math.sqrt(((s-a)*(s-b)*(s-c)) / s );
+
+		return inradius;
+	}
+
+	// --- start of generated output --- //
+
+	// preperations for parameterized vertex coordinates 
+	const vertexParametriziation = false;
+	// generate the faces color by color 
+	const geometry1 = new THREE.BufferGeometry();
+	function setVertices1(){
+		var vertices1 = new Float32Array( [
+				0.,0.,1.,
+			1.,0.,1,
+			0.,2.,1.,
+
+			1.,0.,1,
+			1.5,0,1,
+			0.5,1.,1,
+
+					] ); 
+
+		return vertices1; 
+	}
+
+	geometry1.setAttribute( 'position', new THREE.BufferAttribute( setVertices1(), 3 ) );
+
+	// generate materials in the given color and normals material for the faces 
+
+    const materialNormal1 = new THREE.MeshNormalMaterial({
+        flatShading: true,
+    });
+    materialNormal1.transparent = true;
+    materialNormal1.side = THREE.DoubleSide;
+        
+    const material1 = new THREE.MeshPhongMaterial({
+        color: 0x049EF4,
+        flatShading: true,
+    });
+    material1.transparent = true;
+    material1.side = THREE.DoubleSide;
+        
+	// generate meshes for the faces from the materials with the vertex coordinates from before 
+
+    const mesh1 = new THREE.Mesh( geometry1, material1 );
+    mesh1.castShadow = true;                         
+    mesh1.receiveShadow = true;                      
+                                
+    meshRoot.add(mesh1);
+        
+    const meshNormal1 = new THREE.Mesh( geometry1, materialNormal1 );
+    mesh1.castShadow = true;                         
+    mesh1.receiveShadow = true;                      
+                                
+    normalMeshRoot.add(meshNormal1);
+        
+	// generate the edges grouped by color
+		controlFolder.remove(edgeWidthGUI);
+
+    const edgeMaterial1 = new THREE.LineBasicMaterial( {
+        color: 0x000000,
+        linewidth: 3.,
+    } );
+        
+	function getEdges1(){
+		const edges1 = new Float32Array( [
+			0.,0.,1.,
+			1.,0.,1,
+
+			0.,0.,1.,
+			0.,2.,1.,
+
+			1.,0.,1,
+			0.,2.,1.,
+
+			1.,0.,1,
+			1.5,0,1,
+
+			1.,0.,1,
+			0.5,1.,1,
+
+			1.5,0,1,
+			0.5,1.,1,
+
+		]);
+		return edges1;
+	}
+
+
+	// generate geometries and lines for the edges 
+
+    const edgeGeometry1 = new THREE.BufferGeometry();
+    edgeGeometry1.setAttribute( 'position', new THREE.BufferAttribute( getEdges1(), 3 ) );
+
+    const edgeLine1 = new THREE.LineSegments( edgeGeometry1, edgeMaterial1 );
+    edgeRoot.add(edgeLine1);
+        
+	// update function to be called every frame 
+	// generate labels and spheres for the vertices
+
+
+	function getVertex1(){
+		return [0.,0.,1.,];
+	}
+	const sphereMaterial1 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere1 = new THREE.Mesh( sphereGeometry, sphereMaterial1 );
+	vertexRoot.add(sphere1);
+	sphere1.position.set(getVertex1()[0],getVertex1()[1],getVertex1()[2]);
+
+    const lableDiv1 = document.createElement( 'div' );
+    lableDiv1.className = 'label';
+    lableDiv1.textContent = '1';
+    lableDiv1.style.marginTop = '-1em';
+
+    const vertexLabel1 = new CSS2DObject( lableDiv1 );
+    vertexLabel1.position.set(getVertex1()[0],getVertex1()[1],getVertex1()[2]);
+    vertexlabelRoot.add( vertexLabel1 );
+            
+            
+
+	function getVertex2(){
+		return [1.,0.,1,];
+	}
+	const sphereMaterial2 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere2 = new THREE.Mesh( sphereGeometry, sphereMaterial2 );
+	vertexRoot.add(sphere2);
+	sphere2.position.set(getVertex2()[0],getVertex2()[1],getVertex2()[2]);
+
+    const lableDiv2 = document.createElement( 'div' );
+    lableDiv2.className = 'label';
+    lableDiv2.textContent = '2';
+    lableDiv2.style.marginTop = '-1em';
+
+    const vertexLabel2 = new CSS2DObject( lableDiv2 );
+    vertexLabel2.position.set(getVertex2()[0],getVertex2()[1],getVertex2()[2]);
+    vertexlabelRoot.add( vertexLabel2 );
+            
+            
+
+	function getVertex3(){
+		return [0.,2.,1.,];
+	}
+	const sphereMaterial3 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere3 = new THREE.Mesh( sphereGeometry, sphereMaterial3 );
+	vertexRoot.add(sphere3);
+	sphere3.position.set(getVertex3()[0],getVertex3()[1],getVertex3()[2]);
+
+    const lableDiv3 = document.createElement( 'div' );
+    lableDiv3.className = 'label';
+    lableDiv3.textContent = '3';
+    lableDiv3.style.marginTop = '-1em';
+
+    const vertexLabel3 = new CSS2DObject( lableDiv3 );
+    vertexLabel3.position.set(getVertex3()[0],getVertex3()[1],getVertex3()[2]);
+    vertexlabelRoot.add( vertexLabel3 );
+            
+            
+
+	function getVertex4(){
+		return [1.5,0,1,];
+	}
+	const sphereMaterial4 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere4 = new THREE.Mesh( sphereGeometry, sphereMaterial4 );
+	vertexRoot.add(sphere4);
+	sphere4.position.set(getVertex4()[0],getVertex4()[1],getVertex4()[2]);
+
+    const lableDiv4 = document.createElement( 'div' );
+    lableDiv4.className = 'label';
+    lableDiv4.textContent = '4';
+    lableDiv4.style.marginTop = '-1em';
+
+    const vertexLabel4 = new CSS2DObject( lableDiv4 );
+    vertexLabel4.position.set(getVertex4()[0],getVertex4()[1],getVertex4()[2]);
+    vertexlabelRoot.add( vertexLabel4 );
+            
+            
+
+	function getVertex5(){
+		return [0.5,1.,1,];
+	}
+	const sphereMaterial5 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere5 = new THREE.Mesh( sphereGeometry, sphereMaterial5 );
+	vertexRoot.add(sphere5);
+	sphere5.position.set(getVertex5()[0],getVertex5()[1],getVertex5()[2]);
+
+    const lableDiv5 = document.createElement( 'div' );
+    lableDiv5.className = 'label';
+    lableDiv5.textContent = '5';
+    lableDiv5.style.marginTop = '-1em';
+
+    const vertexLabel5 = new CSS2DObject( lableDiv5 );
+    vertexLabel5.position.set(getVertex5()[0],getVertex5()[1],getVertex5()[2]);
+    vertexlabelRoot.add( vertexLabel5 );
+            
+            	// generate the rings for the incircles 
+
+	var inradius1 = calulateInradius(getVertex1(), getVertex2(), getVertex3());
+	var incenter1 = calulateIncenter(getVertex1(), getVertex2(), getVertex3());
+	var ringGeometry1 = new THREE.RingGeometry((inradius1 - 0.005),inradius1, 32);
+	const ringMaterial1 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh1 = new THREE.Mesh(ringGeometry1, ringMaterial1);
+
+	function setCircleRotation1(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.,0.,1.],[ 1.,0.,1],[0.,2.,1.]);
+
+        ringMesh1.position.setX(incenter[0]);
+        ringMesh1.position.setY(incenter[1]);
+        ringMesh1.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex1(), getVertex2(), getVertex3());
+        var relRadius = inradius/inradius1;
+
+        ringMesh1.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A1 = new THREE.Vector3(0.,0.,1.);
+        const B1 = new THREE.Vector3(1.,0.,1);
+        const C1 = new THREE.Vector3(0.,2.,1.);
+
+        const normalVec1 = new THREE.Vector3();
+        normalVec1.crossVectors(B1.sub(A1), C1.sub(A1));
+        normalVec1.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal1 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation1 = new THREE.Quaternion();
+        quaternionRotation1.setFromUnitVectors(initialNormal1, normalVec1);
+
+        ringMesh1.setRotationFromQuaternion(quaternionRotation1);
+
+        return quaternionRotation1;
+    }
+
+    ringRoot.add(ringMesh1);
+            
+	var inradius2 = calulateInradius(getVertex2(), getVertex4(), getVertex5());
+	var incenter2 = calulateIncenter(getVertex2(), getVertex4(), getVertex5());
+	var ringGeometry2 = new THREE.RingGeometry((inradius2 - 0.005),inradius2, 32);
+	const ringMaterial2 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh2 = new THREE.Mesh(ringGeometry2, ringMaterial2);
+
+	function setCircleRotation2(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([1.,0.,1],[ 1.5,0,1],[0.5,1.,1]);
+
+        ringMesh2.position.setX(incenter[0]);
+        ringMesh2.position.setY(incenter[1]);
+        ringMesh2.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex2(), getVertex4(), getVertex5());
+        var relRadius = inradius/inradius2;
+
+        ringMesh2.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A2 = new THREE.Vector3(1.,0.,1);
+        const B2 = new THREE.Vector3(1.5,0,1);
+        const C2 = new THREE.Vector3(0.5,1.,1);
+
+        const normalVec2 = new THREE.Vector3();
+        normalVec2.crossVectors(B2.sub(A2), C2.sub(A2));
+        normalVec2.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal2 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation2 = new THREE.Quaternion();
+        quaternionRotation2.setFromUnitVectors(initialNormal2, normalVec2);
+
+        ringMesh2.setRotationFromQuaternion(quaternionRotation2);
+
+        return quaternionRotation2;
+    }
+
+    ringRoot.add(ringMesh2);
+            	// function to update the circles every frame 
+	function updateCircles(){
+		setCircleRotation1();
+		setCircleRotation2();
+	}
+
+	// needs to be called once to be initialized 
+	updateCircles();
+
+	// function to update the circles width, that is called every frame even if the surface is not parameterized 
+	function updateCircleWidth(){
+		ringGeometry1.dispose();
+		ringGeometry1 = new THREE.RingGeometry((inradius1 - guiParameters.circleWidth),inradius1, 32);
+		ringMesh1.geometry = ringGeometry1; 
+		ringGeometry2.dispose();
+		ringGeometry2 = new THREE.RingGeometry((inradius2 - guiParameters.circleWidth),inradius2, 32);
+		ringMesh2.geometry = ringGeometry2; 
+	}
+
+	updateCircleWidth();
+
+	// generate the normals trough the incenter orthogonal to the face 
+	// getNormalsVectors generates the coordinates for the current values of the parameterized surface 
+	function getNormalsVectors(){
+		var vector1;
+		var vector2;
+
+		var normals = [];
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (1.)-(0.);
+		vector1[1] = (0.)-(0.);
+		vector1[2] = (1)-(1.);
+
+		vector2[0] = (0.)-(0.);
+		vector2[1] = (2.)-(0.);
+		vector2[2] = (1.)-(1.);
+
+		var incenter = calulateIncenter([0.,0.,1.],[ 1.,0.,1],[0.,2.,1.]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (1.5)-(1.);
+		vector1[1] = (0)-(0.);
+		vector1[2] = (1)-(1);
+
+		vector2[0] = (0.5)-(1.);
+		vector2[1] = (1.)-(0.);
+		vector2[2] = (1)-(1);
+
+		var incenter = calulateIncenter([1.,0.,1],[ 1.5,0,1],[0.5,1.,1]);
+		normals.push([vector1, vector2, incenter]);
+
+	return normals;
+	}
+	// getNormalsCoordinates calculates the right coordinates for the ortogonality and fitting values from the gui 
+	function getNormalsCoordinates(){
+		var res = [];
+		var normals = getNormalsVectors(); 
+        for(var i = 0; i < normals.length; i++){
+            var plus = [];
+            var minus = [];
+
+            minus[0] = normals[i][2][0] - (1/2)*guiParameters.normalsLength*(normals[i][0][1]*normals[i][1][2] - normals[i][0][2]*normals[i][1][1]);
+            minus[1] = normals[i][2][1] - (1/2)*guiParameters.normalsLength*(normals[i][0][2]*normals[i][1][0] - normals[i][0][0]*normals[i][1][2]);
+            minus[2] = normals[i][2][2] - (1/2)*guiParameters.normalsLength*(normals[i][0][0]*normals[i][1][1] - normals[i][0][1]*normals[i][1][0]);
+
+            plus[0] = normals[i][2][0] + (1/2)*guiParameters.normalsLength*(normals[i][0][1]*normals[i][1][2] - normals[i][0][2]*normals[i][1][1]);
+            plus[1] = normals[i][2][1] + (1/2)*guiParameters.normalsLength*(normals[i][0][2]*normals[i][1][0] - normals[i][0][0]*normals[i][1][2]);
+            plus[2] = normals[i][2][2] + (1/2)*guiParameters.normalsLength*(normals[i][0][0]*normals[i][1][1] - normals[i][0][1]*normals[i][1][0]);
+
+            res.push(minus[0]);
+            res.push(minus[1]);
+            res.push(minus[2]);
+            res.push(plus[0]);
+            res.push(plus[1]);
+            res.push(plus[2]);
+        }
+        res = Float32Array.from(res);
+
+    
+		return res;
+	}
+
+
+    const normalsMaterial = new THREE.LineBasicMaterial( {
+        color: 0x000000,
+    } );
+    
+    const normalsGeometry = new THREE.BufferGeometry();
+    normalsGeometry.setAttribute( 'position', new THREE.BufferAttribute( getNormalsCoordinates(), 3 ) );
+    var normalsLine = new THREE.LineSegments( normalsGeometry, normalsMaterial );
+
+    function updateNormals(){
+        normalsGeometry.setAttribute( 'position', new THREE.BufferAttribute( getNormalsCoordinates(), 3 ) );
+        normalsLine = new THREE.LineSegments( normalsGeometry, normalsMaterial );
+    }
+    
+    normalsRoot.add(normalsLine);
+
+    
+	// generate automatic ranges for the intersections if the surface is not parameterized 
+	guiParameters.maxX = 1.5;
+	guiParameters.maxY = 2.;
+	guiParameters.maxZ = 1.;
+	guiParameters.minX = 0.;
+	guiParameters.minY = 0.;
+	guiParameters.minZ = 0.;
+
+	guiParameters.planeX = 0.75;
+	guiParameters.planeY = 1.;
+	guiParameters.planeZ = 0.5;
+	// --- end of generated output --- //
+
+    const planeFolder = gui.addFolder("Intersection Planes");
+    planeFolder.add(guiParameters, 'planeXactive');
+    planeFolder.add(guiParameters, 'planeX', guiParameters.minX*1.1, guiParameters.maxX*1.1);
+    planeFolder.add(guiParameters, 'planeYactive');
+    planeFolder.add(guiParameters, 'planeY', guiParameters.minY*1.1, guiParameters.maxY*1.1);
+    planeFolder.add(guiParameters, 'planeZactive');
+    planeFolder.add(guiParameters, 'planeZ', guiParameters.minZ*1.1, guiParameters.maxZ*1.1);
+    
+    camera.position.z = Math.max((1.5)*guiParameters.minZ, 1)
+    camera.lookAt(0,0,-1);
+
+    scene.background = new THREE.Color( 'white' );
+
+    // add both roots to the scene
+    scene.add( meshRoot );
+    scene.add( wireRoot );
+    scene.add( vertexRoot );
+    scene.add( vertexlabelRoot );
+    scene.add( edgeRoot );
+    scene.add( ringRoot );
+    scene.add( normalsRoot );
+    scene.add( normalMeshRoot );
+
+    //presave some current gui parameters to only update if they change
+    var currentCircleWidth = guiParameters.circleWidth;
+
+    function animate() {
+        requestAnimationFrame( animate );
+        meshRoot.rotation.x += guiParameters.speedX/100;
+        meshRoot.rotation.y += guiParameters.speedY/100;
+        meshRoot.rotation.z += guiParameters.speedZ/100;
+
+        wireRoot.rotation.x += guiParameters.speedX/100;
+        wireRoot.rotation.y += guiParameters.speedY/100;
+        wireRoot.rotation.z += guiParameters.speedZ/100;
+
+        vertexRoot.rotation.x += guiParameters.speedX/100;
+        vertexRoot.rotation.y += guiParameters.speedY/100;
+        vertexRoot.rotation.z += guiParameters.speedZ/100;
+
+        vertexlabelRoot.rotation.x += guiParameters.speedX/100;
+        vertexlabelRoot.rotation.y += guiParameters.speedY/100;
+        vertexlabelRoot.rotation.z += guiParameters.speedZ/100;
+
+        edgeRoot.rotation.x += guiParameters.speedX/100;
+        edgeRoot.rotation.y += guiParameters.speedY/100;
+        edgeRoot.rotation.z += guiParameters.speedZ/100;
+
+        ringRoot.rotation.x += guiParameters.speedX/100;
+        ringRoot.rotation.y += guiParameters.speedY/100;
+        ringRoot.rotation.z += guiParameters.speedZ/100;
+
+        normalsRoot.rotation.x += guiParameters.speedX/100;
+        normalsRoot.rotation.y += guiParameters.speedY/100;
+        normalsRoot.rotation.z += guiParameters.speedZ/100;
+
+        normalMeshRoot.rotation.x += guiParameters.speedX/100;
+        normalMeshRoot.rotation.y += guiParameters.speedY/100;
+        normalMeshRoot.rotation.z += guiParameters.speedZ/100;
+
+        //update the light when the camera moves (with orbitcontrols)
+        light.position.set(camera.position.x, camera.position.y, camera.position.z);
+
+        planeX.constant = guiParameters.planeX;
+        planeY.constant = guiParameters.planeY;
+        planeZ.constant = guiParameters.planeZ;
+
+        activePlanes = [];
+        if(guiParameters.planeXactive){
+            activePlanes.push(planeX);
+        }
+        if(guiParameters.planeYactive){
+            activePlanes.push(planeY);
+        }
+        if(guiParameters.planeZactive){
+            activePlanes.push(planeZ);
+        }
+
+        if(vertexParametriziation){
+            updateFaceCoordinates();
+            if(guiParameters.edgeVisibility){
+                updateEdgeCoordinates();
+            }
+            if(guiParameters.vertexlabelVisibility || guiParameters.vertexVisibility){
+                updateVertexCoordinates();
+            }
+            if(guiParameters.circleVisibility){
+                updateCircles();
+            }
+        }                
+
+        //update stuff that changes from the gui
+        meshRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.opacity = guiParameters.transparency;
+                node.material.clippingPlanes = activePlanes;
+                if(guiParameters.normalsMaterial){
+                    node.material.opacity = 0;
+                }
+            }
+        } );
+
+        normalMeshRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.opacity = guiParameters.transparency;
+                node.material.clippingPlanes = activePlanes;
+                if(!guiParameters.normalsMaterial){
+                    node.material.opacity = 0;
+                }
+            }
+        } );
+
+        edgeRoot.traverse( function( node ) {
+            if ( node instanceof Line2 ) {
+                node.material.visible = guiParameters.edgeVisibility;
+                node.material.linewidth = guiParameters.edgeWidth/100;
+            }
+            if ( node instanceof THREE.LineSegments ) {
+                node.material.visible = guiParameters.edgeVisibility;
+            }
+        } );
+
+        vertexRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.visible = guiParameters.vertexVisibility;
+                node.scale.setScalar(guiParameters.vertexSize);
+            }
+        } );
+
+        vertexlabelRoot.traverse( function( node ) {
+            if( node instanceof CSS2DObject) {
+                node.visible = guiParameters.vertexlabelVisibility;
+            }
+        } );
+
+        ringRoot.traverse( function( node ) {
+            if( node instanceof THREE.Mesh) {
+                node.visible = guiParameters.circleVisibility;
+            }
+        } );
+
+        normalsRoot.traverse( function( node ) {
+            if( node instanceof THREE.LineSegments) {
+                node.visible = guiParameters.normalsVisibility;
+            }
+        } );
+
+        // update the circle width
+        if(guiParameters.circleVisibility && currentCircleWidth != guiParameters.circleWidth){
+            updateCircleWidth();
+            currentCircleWidth = guiParameters.circleWidth;
+        }
+
+        //update the normals length 
+        if(guiParameters.normalsVisibility){
+            updateNormals();
+        }
+
+        controls.update();
+
+        renderer.localClippingEnabled = true;
+
+        renderer.render( scene, camera );
+        labelRenderer.render( scene, camera );
+    }
+    animate();
+
+    //resize of window size changes
+    window.addEventListener( 'resize', onWindowResize );
+    function onWindowResize() {
+        camera.aspect = window.innerWidth / window.innerHeight;
+        camera.updateProjectionMatrix();
+
+        renderer.setSize( window.innerWidth, window.innerHeight );
+        labelRenderer.setSize( window.innerWidth, window.innerHeight );
+    }
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/htmls/TwoFacesIntersection.html b/htmls/TwoFacesIntersection.html
new file mode 100644
index 0000000000000000000000000000000000000000..0a31cc69514120f98718bab78917616197398880
--- /dev/null
+++ b/htmls/TwoFacesIntersection.html
@@ -0,0 +1,761 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="utf-8">
+		<title>SimplicialSurface</title>
+		<style>
+			body { margin: 0; }
+		</style>
+
+
+	</head>
+	<body>
+
+<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>
+
+
+<script type="importmap">
+	{
+		"imports": {
+			"three": "https://unpkg.com/three@0.148.0/build/three.module.js",
+			"three/addons/": "https://unpkg.com/three@0.148.0/examples/jsm/",
+			"gui": "https://unpkg.com/dat.gui@0.7.9/build/dat.gui.module.js"
+		}
+	}
+</script>
+
+
+<script type="module">
+	import * as THREE from 'three';
+	import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
+	import { GUI } from 'gui';
+	import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
+	import { Line2 } from 'three/addons/lines/Line2.js';
+	import { LineMaterial } from 'three/addons/lines/LineMaterial.js';
+	import { LineGeometry } from 'three/addons/lines/LineGeometry.js';
+
+	//start scene and camera
+	const scene = new THREE.Scene();
+	const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 100 );
+
+	const renderer = new THREE.WebGLRenderer({ antialias: true });
+	renderer.setSize( window.innerWidth, window.innerHeight );
+	document.body.appendChild( renderer.domElement );
+
+	//Lights
+	const skyColor = 0xFFFFFF;
+	const skyIntensity = 0.3;
+	const skyLight = new THREE.AmbientLight(skyColor, skyIntensity);
+	scene.add(skyLight);
+
+	const color = 0xFFFFFF;
+	const intensity = 1;
+	const light = new THREE.PointLight(color, intensity);
+	light.position.set(0, 3, -5);
+	scene.add(light);
+
+	//create groups to add everything to
+	const meshRoot = new THREE.Group();
+	const wireRoot = new THREE.Group();
+	const vertexRoot = new THREE.Group();
+	const vertexlabelRoot = new THREE.Group();
+	const edgeRoot = new THREE.Group();
+	const ringRoot = new THREE.Group();
+	const normalsRoot = new THREE.Group();
+	const normalMeshRoot = new THREE.Group();
+
+	//parameters for the controls on the top right
+	var guiParameters = new function() { 
+		this.speedX = 0.0; 
+		this.speedY = 0.0; 
+		this.speedZ = 0.0;
+		this.transparency = 1;
+		this.edgeVisibility = false;
+		this.edgeWidth = 0.2;
+
+		this.vertexVisibility = true;
+		this.vertexlabelVisibility = false;
+		this.vertexSize = 1;
+		this.planeX = 0.0;
+		this.minX = -1.5;
+		this.maxX = 1.5;
+		this.planeXactive = false;
+		this.planeY = 0.0;
+		this.minY = -1.5;
+
+		this.maxY = 1.5;
+		this.planeYactive = false;
+		this.planeZ = 0.0;
+		this.minZ = -1.5;
+		this.maxZ = 1.5;
+		this.planeZactive = false;
+		this.normalsMaterial = false;
+		this.circleVisibility = false;
+		this.circleWidth = 0.005;
+		this.normalsVisibility = false;
+		this.normalsLength = 1;
+	} ;
+
+	//generate the plane for intersections
+	const planeX = new THREE.Plane( new THREE.Vector3( -1, 0, 0 ), guiParameters.planeX );
+	const planeY = new THREE.Plane( new THREE.Vector3( 0, -1, 0 ), guiParameters.planeY );
+	const planeZ = new THREE.Plane( new THREE.Vector3( 0, 0, -1 ), guiParameters.planeZ );
+
+	// the array which ones are currently active
+	var activePlanes = [];
+
+	//rederer for lables
+	const labelRenderer = new CSS2DRenderer();
+	labelRenderer.setSize( window.innerWidth, window.innerHeight );
+	labelRenderer.domElement.style.position = 'absolute';
+	labelRenderer.domElement.style.top = '0px';
+	document.body.appendChild( labelRenderer.domElement );
+	
+	//controls for mouse 
+	const controls = new OrbitControls( camera, labelRenderer.domElement );
+
+	//controls in the top right corner
+	var gui = new GUI();
+
+	const animationFolder = gui.addFolder("Animations");
+	animationFolder.add(guiParameters, 'speedX', 0, 5);
+	animationFolder.add(guiParameters, 'speedY', 0, 5);
+	animationFolder.add(guiParameters, 'speedZ', 0, 5);
+	animationFolder.open();
+
+	const controlFolder = gui.addFolder("Controls");
+	controlFolder.add(guiParameters, "transparency", 0, 1);
+	controlFolder.add(guiParameters, "edgeVisibility");
+	var edgeWidthGUI = controlFolder.add(guiParameters, "edgeWidth", 0.01, 2);
+	controlFolder.add(guiParameters, "vertexVisibility");
+	controlFolder.add(guiParameters, "vertexlabelVisibility");
+	controlFolder.add(guiParameters, "vertexSize", 0.1, 3);
+	controlFolder.add(guiParameters, "normalsMaterial");
+	controlFolder.add(guiParameters, "circleVisibility");
+	controlFolder.add(guiParameters, "circleWidth", 0.0001, 0.1);
+	controlFolder.add(guiParameters, "normalsVisibility");
+	controlFolder.add(guiParameters, "normalsLength", 0, 2);
+	controlFolder.open();
+
+	//generate a sphere geometry for the vertices
+	const sphereGeometry = new THREE.SphereGeometry( 0.02, 32, 16 );
+	sphereGeometry.transparent = guiParameters.vertexVisibility;
+	
+	//functions for later calculations
+
+	function calulateIncenter(A, B, C){
+		//we follow the math and variable names from here: https://math.stackexchange.com/questions/740111/incenter-of-triangle-in-3d
+		var a = Math.sqrt((B[0]-C[0])**2 + (B[1]-C[1])**2 + (B[2]-C[2])**2);
+		var b = Math.sqrt((C[0]-A[0])**2 + (C[1]-A[1])**2 + (C[2]-A[2])**2);
+		var c = Math.sqrt((A[0]-B[0])**2 + (A[1]-B[1])**2 + (A[2]-B[2])**2);
+
+		var res = [];
+		res[0] = a/(a+b+c)*A[0] + b/(a+b+c)*B[0] + c/(a+b+c)*C[0];
+		res[1] = a/(a+b+c)*A[1] + b/(a+b+c)*B[1] + c/(a+b+c)*C[1];
+		res[2] = a/(a+b+c)*A[2] + b/(a+b+c)*B[2] + c/(a+b+c)*C[2];
+
+		return res;
+	}
+
+	function calulateInradius(A, B, C){
+		var a = Math.sqrt((B[0]-C[0])**2 + (B[1]-C[1])**2 + (B[2]-C[2])**2);
+		var b = Math.sqrt((C[0]-A[0])**2 + (C[1]-A[1])**2 + (C[2]-A[2])**2);
+		var c = Math.sqrt((A[0]-B[0])**2 + (A[1]-B[1])**2 + (A[2]-B[2])**2);
+
+		var s = (a+b+c)/2;
+		var inradius = Math.sqrt(((s-a)*(s-b)*(s-c)) / s );
+
+		return inradius;
+	}
+
+	// --- start of generated output --- //
+
+	// preperations for parameterized vertex coordinates 
+	const vertexParametriziation = false;
+	// generate the faces color by color 
+	const geometry1 = new THREE.BufferGeometry();
+	function setVertices1(){
+		var vertices1 = new Float32Array( [
+				1.,0.,0.,
+			-1.,0.,0.,
+			0.,2.,0.,
+
+			0.5,0.5,0.5,
+			0.5,0.5,-0.5,
+			1.5,1,0,
+
+					] ); 
+
+		return vertices1; 
+	}
+
+	geometry1.setAttribute( 'position', new THREE.BufferAttribute( setVertices1(), 3 ) );
+
+	// generate materials in the given color and normals material for the faces 
+
+    const materialNormal1 = new THREE.MeshNormalMaterial({
+        flatShading: true,
+    });
+    materialNormal1.transparent = true;
+    materialNormal1.side = THREE.DoubleSide;
+        
+    const material1 = new THREE.MeshPhongMaterial({
+        color: 0x049EF4,
+        flatShading: true,
+    });
+    material1.transparent = true;
+    material1.side = THREE.DoubleSide;
+        
+	// generate meshes for the faces from the materials with the vertex coordinates from before 
+
+    const mesh1 = new THREE.Mesh( geometry1, material1 );
+    mesh1.castShadow = true;                         
+    mesh1.receiveShadow = true;                      
+                                
+    meshRoot.add(mesh1);
+        
+    const meshNormal1 = new THREE.Mesh( geometry1, materialNormal1 );
+    mesh1.castShadow = true;                         
+    mesh1.receiveShadow = true;                      
+                                
+    normalMeshRoot.add(meshNormal1);
+        
+	// generate the edges grouped by color
+		controlFolder.remove(edgeWidthGUI);
+
+    const edgeMaterial1 = new THREE.LineBasicMaterial( {
+        color: 0x000000,
+        linewidth: 3.,
+    } );
+        
+	function getEdges1(){
+		const edges1 = new Float32Array( [
+			1.,0.,0.,
+			-1.,0.,0.,
+
+			1.,0.,0.,
+			0.,2.,0.,
+
+			-1.,0.,0.,
+			0.,2.,0.,
+
+			0.5,0.5,0.5,
+			0.5,0.5,-0.5,
+
+			0.5,0.5,0.5,
+			1.5,1,0,
+
+			0.5,0.5,-0.5,
+			1.5,1,0,
+
+		]);
+		return edges1;
+	}
+
+
+	// generate geometries and lines for the edges 
+
+    const edgeGeometry1 = new THREE.BufferGeometry();
+    edgeGeometry1.setAttribute( 'position', new THREE.BufferAttribute( getEdges1(), 3 ) );
+
+    const edgeLine1 = new THREE.LineSegments( edgeGeometry1, edgeMaterial1 );
+    edgeRoot.add(edgeLine1);
+        
+	// update function to be called every frame 
+	// generate labels and spheres for the vertices
+
+
+	function getVertex1(){
+		return [1.,0.,0.,];
+	}
+	const sphereMaterial1 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere1 = new THREE.Mesh( sphereGeometry, sphereMaterial1 );
+	vertexRoot.add(sphere1);
+	sphere1.position.set(getVertex1()[0],getVertex1()[1],getVertex1()[2]);
+
+    const lableDiv1 = document.createElement( 'div' );
+    lableDiv1.className = 'label';
+    lableDiv1.textContent = '1';
+    lableDiv1.style.marginTop = '-1em';
+
+    const vertexLabel1 = new CSS2DObject( lableDiv1 );
+    vertexLabel1.position.set(getVertex1()[0],getVertex1()[1],getVertex1()[2]);
+    vertexlabelRoot.add( vertexLabel1 );
+            
+            
+
+	function getVertex2(){
+		return [-1.,0.,0.,];
+	}
+	const sphereMaterial2 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere2 = new THREE.Mesh( sphereGeometry, sphereMaterial2 );
+	vertexRoot.add(sphere2);
+	sphere2.position.set(getVertex2()[0],getVertex2()[1],getVertex2()[2]);
+
+    const lableDiv2 = document.createElement( 'div' );
+    lableDiv2.className = 'label';
+    lableDiv2.textContent = '2';
+    lableDiv2.style.marginTop = '-1em';
+
+    const vertexLabel2 = new CSS2DObject( lableDiv2 );
+    vertexLabel2.position.set(getVertex2()[0],getVertex2()[1],getVertex2()[2]);
+    vertexlabelRoot.add( vertexLabel2 );
+            
+            
+
+	function getVertex3(){
+		return [0.,2.,0.,];
+	}
+	const sphereMaterial3 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere3 = new THREE.Mesh( sphereGeometry, sphereMaterial3 );
+	vertexRoot.add(sphere3);
+	sphere3.position.set(getVertex3()[0],getVertex3()[1],getVertex3()[2]);
+
+    const lableDiv3 = document.createElement( 'div' );
+    lableDiv3.className = 'label';
+    lableDiv3.textContent = '3';
+    lableDiv3.style.marginTop = '-1em';
+
+    const vertexLabel3 = new CSS2DObject( lableDiv3 );
+    vertexLabel3.position.set(getVertex3()[0],getVertex3()[1],getVertex3()[2]);
+    vertexlabelRoot.add( vertexLabel3 );
+            
+            
+
+	function getVertex4(){
+		return [0.5,0.5,0.5,];
+	}
+	const sphereMaterial4 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere4 = new THREE.Mesh( sphereGeometry, sphereMaterial4 );
+	vertexRoot.add(sphere4);
+	sphere4.position.set(getVertex4()[0],getVertex4()[1],getVertex4()[2]);
+
+    const lableDiv4 = document.createElement( 'div' );
+    lableDiv4.className = 'label';
+    lableDiv4.textContent = '4';
+    lableDiv4.style.marginTop = '-1em';
+
+    const vertexLabel4 = new CSS2DObject( lableDiv4 );
+    vertexLabel4.position.set(getVertex4()[0],getVertex4()[1],getVertex4()[2]);
+    vertexlabelRoot.add( vertexLabel4 );
+            
+            
+
+	function getVertex5(){
+		return [0.5,0.5,-0.5,];
+	}
+	const sphereMaterial5 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere5 = new THREE.Mesh( sphereGeometry, sphereMaterial5 );
+	vertexRoot.add(sphere5);
+	sphere5.position.set(getVertex5()[0],getVertex5()[1],getVertex5()[2]);
+
+    const lableDiv5 = document.createElement( 'div' );
+    lableDiv5.className = 'label';
+    lableDiv5.textContent = '5';
+    lableDiv5.style.marginTop = '-1em';
+
+    const vertexLabel5 = new CSS2DObject( lableDiv5 );
+    vertexLabel5.position.set(getVertex5()[0],getVertex5()[1],getVertex5()[2]);
+    vertexlabelRoot.add( vertexLabel5 );
+            
+            
+
+	function getVertex6(){
+		return [1.5,1,0,];
+	}
+	const sphereMaterial6 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere6 = new THREE.Mesh( sphereGeometry, sphereMaterial6 );
+	vertexRoot.add(sphere6);
+	sphere6.position.set(getVertex6()[0],getVertex6()[1],getVertex6()[2]);
+
+    const lableDiv6 = document.createElement( 'div' );
+    lableDiv6.className = 'label';
+    lableDiv6.textContent = '6';
+    lableDiv6.style.marginTop = '-1em';
+
+    const vertexLabel6 = new CSS2DObject( lableDiv6 );
+    vertexLabel6.position.set(getVertex6()[0],getVertex6()[1],getVertex6()[2]);
+    vertexlabelRoot.add( vertexLabel6 );
+            
+            	// generate the rings for the incircles 
+
+	var inradius1 = calulateInradius(getVertex1(), getVertex2(), getVertex3());
+	var incenter1 = calulateIncenter(getVertex1(), getVertex2(), getVertex3());
+	var ringGeometry1 = new THREE.RingGeometry((inradius1 - 0.005),inradius1, 32);
+	const ringMaterial1 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh1 = new THREE.Mesh(ringGeometry1, ringMaterial1);
+
+	function setCircleRotation1(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([1.,0.,0.],[ -1.,0.,0.],[0.,2.,0.]);
+
+        ringMesh1.position.setX(incenter[0]);
+        ringMesh1.position.setY(incenter[1]);
+        ringMesh1.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex1(), getVertex2(), getVertex3());
+        var relRadius = inradius/inradius1;
+
+        ringMesh1.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A1 = new THREE.Vector3(1.,0.,0.);
+        const B1 = new THREE.Vector3(-1.,0.,0.);
+        const C1 = new THREE.Vector3(0.,2.,0.);
+
+        const normalVec1 = new THREE.Vector3();
+        normalVec1.crossVectors(B1.sub(A1), C1.sub(A1));
+        normalVec1.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal1 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation1 = new THREE.Quaternion();
+        quaternionRotation1.setFromUnitVectors(initialNormal1, normalVec1);
+
+        ringMesh1.setRotationFromQuaternion(quaternionRotation1);
+
+        return quaternionRotation1;
+    }
+
+    ringRoot.add(ringMesh1);
+            
+	var inradius2 = calulateInradius(getVertex4(), getVertex5(), getVertex6());
+	var incenter2 = calulateIncenter(getVertex4(), getVertex5(), getVertex6());
+	var ringGeometry2 = new THREE.RingGeometry((inradius2 - 0.005),inradius2, 32);
+	const ringMaterial2 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh2 = new THREE.Mesh(ringGeometry2, ringMaterial2);
+
+	function setCircleRotation2(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.5,0.5,0.5],[ 0.5,0.5,-0.5],[1.5,1,0]);
+
+        ringMesh2.position.setX(incenter[0]);
+        ringMesh2.position.setY(incenter[1]);
+        ringMesh2.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex4(), getVertex5(), getVertex6());
+        var relRadius = inradius/inradius2;
+
+        ringMesh2.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A2 = new THREE.Vector3(0.5,0.5,0.5);
+        const B2 = new THREE.Vector3(0.5,0.5,-0.5);
+        const C2 = new THREE.Vector3(1.5,1,0);
+
+        const normalVec2 = new THREE.Vector3();
+        normalVec2.crossVectors(B2.sub(A2), C2.sub(A2));
+        normalVec2.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal2 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation2 = new THREE.Quaternion();
+        quaternionRotation2.setFromUnitVectors(initialNormal2, normalVec2);
+
+        ringMesh2.setRotationFromQuaternion(quaternionRotation2);
+
+        return quaternionRotation2;
+    }
+
+    ringRoot.add(ringMesh2);
+            	// function to update the circles every frame 
+	function updateCircles(){
+		setCircleRotation1();
+		setCircleRotation2();
+	}
+
+	// needs to be called once to be initialized 
+	updateCircles();
+
+	// function to update the circles width, that is called every frame even if the surface is not parameterized 
+	function updateCircleWidth(){
+		ringGeometry1.dispose();
+		ringGeometry1 = new THREE.RingGeometry((inradius1 - guiParameters.circleWidth),inradius1, 32);
+		ringMesh1.geometry = ringGeometry1; 
+		ringGeometry2.dispose();
+		ringGeometry2 = new THREE.RingGeometry((inradius2 - guiParameters.circleWidth),inradius2, 32);
+		ringMesh2.geometry = ringGeometry2; 
+	}
+
+	updateCircleWidth();
+
+	// generate the normals trough the incenter orthogonal to the face 
+	// getNormalsVectors generates the coordinates for the current values of the parameterized surface 
+	function getNormalsVectors(){
+		var vector1;
+		var vector2;
+
+		var normals = [];
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (-1.)-(1.);
+		vector1[1] = (0.)-(0.);
+		vector1[2] = (0.)-(0.);
+
+		vector2[0] = (0.)-(1.);
+		vector2[1] = (2.)-(0.);
+		vector2[2] = (0.)-(0.);
+
+		var incenter = calulateIncenter([1.,0.,0.],[ -1.,0.,0.],[0.,2.,0.]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.5)-(0.5);
+		vector1[1] = (0.5)-(0.5);
+		vector1[2] = (-0.5)-(0.5);
+
+		vector2[0] = (1.5)-(0.5);
+		vector2[1] = (1)-(0.5);
+		vector2[2] = (0)-(0.5);
+
+		var incenter = calulateIncenter([0.5,0.5,0.5],[ 0.5,0.5,-0.5],[1.5,1,0]);
+		normals.push([vector1, vector2, incenter]);
+
+	return normals;
+	}
+	// getNormalsCoordinates calculates the right coordinates for the ortogonality and fitting values from the gui 
+	function getNormalsCoordinates(){
+		var res = [];
+		var normals = getNormalsVectors(); 
+        for(var i = 0; i < normals.length; i++){
+            var plus = [];
+            var minus = [];
+
+            minus[0] = normals[i][2][0] - (1/2)*guiParameters.normalsLength*(normals[i][0][1]*normals[i][1][2] - normals[i][0][2]*normals[i][1][1]);
+            minus[1] = normals[i][2][1] - (1/2)*guiParameters.normalsLength*(normals[i][0][2]*normals[i][1][0] - normals[i][0][0]*normals[i][1][2]);
+            minus[2] = normals[i][2][2] - (1/2)*guiParameters.normalsLength*(normals[i][0][0]*normals[i][1][1] - normals[i][0][1]*normals[i][1][0]);
+
+            plus[0] = normals[i][2][0] + (1/2)*guiParameters.normalsLength*(normals[i][0][1]*normals[i][1][2] - normals[i][0][2]*normals[i][1][1]);
+            plus[1] = normals[i][2][1] + (1/2)*guiParameters.normalsLength*(normals[i][0][2]*normals[i][1][0] - normals[i][0][0]*normals[i][1][2]);
+            plus[2] = normals[i][2][2] + (1/2)*guiParameters.normalsLength*(normals[i][0][0]*normals[i][1][1] - normals[i][0][1]*normals[i][1][0]);
+
+            res.push(minus[0]);
+            res.push(minus[1]);
+            res.push(minus[2]);
+            res.push(plus[0]);
+            res.push(plus[1]);
+            res.push(plus[2]);
+        }
+        res = Float32Array.from(res);
+
+    
+		return res;
+	}
+
+
+    const normalsMaterial = new THREE.LineBasicMaterial( {
+        color: 0x000000,
+    } );
+    
+    const normalsGeometry = new THREE.BufferGeometry();
+    normalsGeometry.setAttribute( 'position', new THREE.BufferAttribute( getNormalsCoordinates(), 3 ) );
+    var normalsLine = new THREE.LineSegments( normalsGeometry, normalsMaterial );
+
+    function updateNormals(){
+        normalsGeometry.setAttribute( 'position', new THREE.BufferAttribute( getNormalsCoordinates(), 3 ) );
+        normalsLine = new THREE.LineSegments( normalsGeometry, normalsMaterial );
+    }
+    
+    normalsRoot.add(normalsLine);
+
+    
+	// generate automatic ranges for the intersections if the surface is not parameterized 
+	guiParameters.maxX = 1.5;
+	guiParameters.maxY = 2.;
+	guiParameters.maxZ = 0.5;
+	guiParameters.minX = -1.;
+	guiParameters.minY = 0.;
+	guiParameters.minZ = -0.5;
+
+	guiParameters.planeX = 0.25;
+	guiParameters.planeY = 1.;
+	guiParameters.planeZ = 0.;
+	// --- end of generated output --- //
+
+    const planeFolder = gui.addFolder("Intersection Planes");
+    planeFolder.add(guiParameters, 'planeXactive');
+    planeFolder.add(guiParameters, 'planeX', guiParameters.minX*1.1, guiParameters.maxX*1.1);
+    planeFolder.add(guiParameters, 'planeYactive');
+    planeFolder.add(guiParameters, 'planeY', guiParameters.minY*1.1, guiParameters.maxY*1.1);
+    planeFolder.add(guiParameters, 'planeZactive');
+    planeFolder.add(guiParameters, 'planeZ', guiParameters.minZ*1.1, guiParameters.maxZ*1.1);
+    
+    camera.position.z = Math.max((1.5)*guiParameters.minZ, 1)
+    camera.lookAt(0,0,-1);
+
+    scene.background = new THREE.Color( 'white' );
+
+    // add both roots to the scene
+    scene.add( meshRoot );
+    scene.add( wireRoot );
+    scene.add( vertexRoot );
+    scene.add( vertexlabelRoot );
+    scene.add( edgeRoot );
+    scene.add( ringRoot );
+    scene.add( normalsRoot );
+    scene.add( normalMeshRoot );
+
+    //presave some current gui parameters to only update if they change
+    var currentCircleWidth = guiParameters.circleWidth;
+
+    function animate() {
+        requestAnimationFrame( animate );
+        meshRoot.rotation.x += guiParameters.speedX/100;
+        meshRoot.rotation.y += guiParameters.speedY/100;
+        meshRoot.rotation.z += guiParameters.speedZ/100;
+
+        wireRoot.rotation.x += guiParameters.speedX/100;
+        wireRoot.rotation.y += guiParameters.speedY/100;
+        wireRoot.rotation.z += guiParameters.speedZ/100;
+
+        vertexRoot.rotation.x += guiParameters.speedX/100;
+        vertexRoot.rotation.y += guiParameters.speedY/100;
+        vertexRoot.rotation.z += guiParameters.speedZ/100;
+
+        vertexlabelRoot.rotation.x += guiParameters.speedX/100;
+        vertexlabelRoot.rotation.y += guiParameters.speedY/100;
+        vertexlabelRoot.rotation.z += guiParameters.speedZ/100;
+
+        edgeRoot.rotation.x += guiParameters.speedX/100;
+        edgeRoot.rotation.y += guiParameters.speedY/100;
+        edgeRoot.rotation.z += guiParameters.speedZ/100;
+
+        ringRoot.rotation.x += guiParameters.speedX/100;
+        ringRoot.rotation.y += guiParameters.speedY/100;
+        ringRoot.rotation.z += guiParameters.speedZ/100;
+
+        normalsRoot.rotation.x += guiParameters.speedX/100;
+        normalsRoot.rotation.y += guiParameters.speedY/100;
+        normalsRoot.rotation.z += guiParameters.speedZ/100;
+
+        normalMeshRoot.rotation.x += guiParameters.speedX/100;
+        normalMeshRoot.rotation.y += guiParameters.speedY/100;
+        normalMeshRoot.rotation.z += guiParameters.speedZ/100;
+
+        //update the light when the camera moves (with orbitcontrols)
+        light.position.set(camera.position.x, camera.position.y, camera.position.z);
+
+        planeX.constant = guiParameters.planeX;
+        planeY.constant = guiParameters.planeY;
+        planeZ.constant = guiParameters.planeZ;
+
+        activePlanes = [];
+        if(guiParameters.planeXactive){
+            activePlanes.push(planeX);
+        }
+        if(guiParameters.planeYactive){
+            activePlanes.push(planeY);
+        }
+        if(guiParameters.planeZactive){
+            activePlanes.push(planeZ);
+        }
+
+        if(vertexParametriziation){
+            updateFaceCoordinates();
+            if(guiParameters.edgeVisibility){
+                updateEdgeCoordinates();
+            }
+            if(guiParameters.vertexlabelVisibility || guiParameters.vertexVisibility){
+                updateVertexCoordinates();
+            }
+            if(guiParameters.circleVisibility){
+                updateCircles();
+            }
+        }                
+
+        //update stuff that changes from the gui
+        meshRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.opacity = guiParameters.transparency;
+                node.material.clippingPlanes = activePlanes;
+                if(guiParameters.normalsMaterial){
+                    node.material.opacity = 0;
+                }
+            }
+        } );
+
+        normalMeshRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.opacity = guiParameters.transparency;
+                node.material.clippingPlanes = activePlanes;
+                if(!guiParameters.normalsMaterial){
+                    node.material.opacity = 0;
+                }
+            }
+        } );
+
+        edgeRoot.traverse( function( node ) {
+            if ( node instanceof Line2 ) {
+                node.material.visible = guiParameters.edgeVisibility;
+                node.material.linewidth = guiParameters.edgeWidth/100;
+            }
+            if ( node instanceof THREE.LineSegments ) {
+                node.material.visible = guiParameters.edgeVisibility;
+            }
+        } );
+
+        vertexRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.visible = guiParameters.vertexVisibility;
+                node.scale.setScalar(guiParameters.vertexSize);
+            }
+        } );
+
+        vertexlabelRoot.traverse( function( node ) {
+            if( node instanceof CSS2DObject) {
+                node.visible = guiParameters.vertexlabelVisibility;
+            }
+        } );
+
+        ringRoot.traverse( function( node ) {
+            if( node instanceof THREE.Mesh) {
+                node.visible = guiParameters.circleVisibility;
+            }
+        } );
+
+        normalsRoot.traverse( function( node ) {
+            if( node instanceof THREE.LineSegments) {
+                node.visible = guiParameters.normalsVisibility;
+            }
+        } );
+
+        // update the circle width
+        if(guiParameters.circleVisibility && currentCircleWidth != guiParameters.circleWidth){
+            updateCircleWidth();
+            currentCircleWidth = guiParameters.circleWidth;
+        }
+
+        //update the normals length 
+        if(guiParameters.normalsVisibility){
+            updateNormals();
+        }
+
+        controls.update();
+
+        renderer.localClippingEnabled = true;
+
+        renderer.render( scene, camera );
+        labelRenderer.render( scene, camera );
+    }
+    animate();
+
+    //resize of window size changes
+    window.addEventListener( 'resize', onWindowResize );
+    function onWindowResize() {
+        camera.aspect = window.innerWidth / window.innerHeight;
+        camera.updateProjectionMatrix();
+
+        renderer.setSize( window.innerWidth, window.innerHeight );
+        labelRenderer.setSize( window.innerWidth, window.innerHeight );
+    }
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/htmls/ico_32.html b/htmls/ico_32.html
new file mode 100644
index 0000000000000000000000000000000000000000..977b3b4732a3624b412e653a3b3d5bfe75504128
--- /dev/null
+++ b/htmls/ico_32.html
@@ -0,0 +1,2099 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="utf-8">
+		<title>SimplicialSurface</title>
+		<style>
+			body { margin: 0; }
+		</style>
+
+
+	</head>
+	<body>
+
+<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>
+
+
+<script type="importmap">
+	{
+		"imports": {
+			"three": "https://unpkg.com/three@0.148.0/build/three.module.js",
+			"three/addons/": "https://unpkg.com/three@0.148.0/examples/jsm/",
+			"gui": "https://unpkg.com/dat.gui@0.7.9/build/dat.gui.module.js"
+		}
+	}
+</script>
+
+
+<script type="module">
+	import * as THREE from 'three';
+	import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
+	import { GUI } from 'gui';
+	import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
+	import { Line2 } from 'three/addons/lines/Line2.js';
+	import { LineMaterial } from 'three/addons/lines/LineMaterial.js';
+	import { LineGeometry } from 'three/addons/lines/LineGeometry.js';
+
+	//start scene and camera
+	const scene = new THREE.Scene();
+	const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 100 );
+
+	const renderer = new THREE.WebGLRenderer({ antialias: true });
+	renderer.setSize( window.innerWidth, window.innerHeight );
+	document.body.appendChild( renderer.domElement );
+
+	//Lights
+	const skyColor = 0xFFFFFF;
+	const skyIntensity = 0.3;
+	const skyLight = new THREE.AmbientLight(skyColor, skyIntensity);
+	scene.add(skyLight);
+
+	const color = 0xFFFFFF;
+	const intensity = 1;
+	const light = new THREE.PointLight(color, intensity);
+	light.position.set(0, 3, -5);
+	scene.add(light);
+
+	//create groups to add everything to
+	const meshRoot = new THREE.Group();
+	const wireRoot = new THREE.Group();
+	const vertexRoot = new THREE.Group();
+	const vertexlabelRoot = new THREE.Group();
+	const edgeRoot = new THREE.Group();
+	const ringRoot = new THREE.Group();
+	const normalsRoot = new THREE.Group();
+	const normalMeshRoot = new THREE.Group();
+
+	//parameters for the controls on the top right
+	var guiParameters = new function() { 
+		this.speedX = 0.0; 
+		this.speedY = 0.0; 
+		this.speedZ = 0.0;
+		this.transparency = 1;
+		this.edgeVisibility = false;
+		this.edgeWidth = 0.2;
+
+		this.vertexVisibility = true;
+		this.vertexlabelVisibility = false;
+		this.vertexSize = 1;
+		this.planeX = 0.0;
+		this.minX = -1.5;
+		this.maxX = 1.5;
+		this.planeXactive = false;
+		this.planeY = 0.0;
+		this.minY = -1.5;
+
+		this.maxY = 1.5;
+		this.planeYactive = false;
+		this.planeZ = 0.0;
+		this.minZ = -1.5;
+		this.maxZ = 1.5;
+		this.planeZactive = false;
+		this.normalsMaterial = false;
+		this.circleVisibility = false;
+		this.circleWidth = 0.005;
+		this.normalsVisibility = false;
+		this.normalsLength = 1;
+	} ;
+
+	//generate the plane for intersections
+	const planeX = new THREE.Plane( new THREE.Vector3( -1, 0, 0 ), guiParameters.planeX );
+	const planeY = new THREE.Plane( new THREE.Vector3( 0, -1, 0 ), guiParameters.planeY );
+	const planeZ = new THREE.Plane( new THREE.Vector3( 0, 0, -1 ), guiParameters.planeZ );
+
+	// the array which ones are currently active
+	var activePlanes = [];
+
+	//rederer for lables
+	const labelRenderer = new CSS2DRenderer();
+	labelRenderer.setSize( window.innerWidth, window.innerHeight );
+	labelRenderer.domElement.style.position = 'absolute';
+	labelRenderer.domElement.style.top = '0px';
+	document.body.appendChild( labelRenderer.domElement );
+	
+	//controls for mouse 
+	const controls = new OrbitControls( camera, labelRenderer.domElement );
+
+	//controls in the top right corner
+	var gui = new GUI();
+
+	const animationFolder = gui.addFolder("Animations");
+	animationFolder.add(guiParameters, 'speedX', 0, 5);
+	animationFolder.add(guiParameters, 'speedY', 0, 5);
+	animationFolder.add(guiParameters, 'speedZ', 0, 5);
+	animationFolder.open();
+
+	const controlFolder = gui.addFolder("Controls");
+	controlFolder.add(guiParameters, "transparency", 0, 1);
+	controlFolder.add(guiParameters, "edgeVisibility");
+	var edgeWidthGUI = controlFolder.add(guiParameters, "edgeWidth", 0.01, 2);
+	controlFolder.add(guiParameters, "vertexVisibility");
+	controlFolder.add(guiParameters, "vertexlabelVisibility");
+	controlFolder.add(guiParameters, "vertexSize", 0.1, 3);
+	controlFolder.add(guiParameters, "normalsMaterial");
+	controlFolder.add(guiParameters, "circleVisibility");
+	controlFolder.add(guiParameters, "circleWidth", 0.0001, 0.1);
+	controlFolder.add(guiParameters, "normalsVisibility");
+	controlFolder.add(guiParameters, "normalsLength", 0, 2);
+	controlFolder.open();
+
+	//generate a sphere geometry for the vertices
+	const sphereGeometry = new THREE.SphereGeometry( 0.02, 32, 16 );
+	sphereGeometry.transparent = guiParameters.vertexVisibility;
+	
+	//functions for later calculations
+
+	function calulateIncenter(A, B, C){
+		//we follow the math and variable names from here: https://math.stackexchange.com/questions/740111/incenter-of-triangle-in-3d
+		var a = Math.sqrt((B[0]-C[0])**2 + (B[1]-C[1])**2 + (B[2]-C[2])**2);
+		var b = Math.sqrt((C[0]-A[0])**2 + (C[1]-A[1])**2 + (C[2]-A[2])**2);
+		var c = Math.sqrt((A[0]-B[0])**2 + (A[1]-B[1])**2 + (A[2]-B[2])**2);
+
+		var res = [];
+		res[0] = a/(a+b+c)*A[0] + b/(a+b+c)*B[0] + c/(a+b+c)*C[0];
+		res[1] = a/(a+b+c)*A[1] + b/(a+b+c)*B[1] + c/(a+b+c)*C[1];
+		res[2] = a/(a+b+c)*A[2] + b/(a+b+c)*B[2] + c/(a+b+c)*C[2];
+
+		return res;
+	}
+
+	function calulateInradius(A, B, C){
+		var a = Math.sqrt((B[0]-C[0])**2 + (B[1]-C[1])**2 + (B[2]-C[2])**2);
+		var b = Math.sqrt((C[0]-A[0])**2 + (C[1]-A[1])**2 + (C[2]-A[2])**2);
+		var c = Math.sqrt((A[0]-B[0])**2 + (A[1]-B[1])**2 + (A[2]-B[2])**2);
+
+		var s = (a+b+c)/2;
+		var inradius = Math.sqrt(((s-a)*(s-b)*(s-c)) / s );
+
+		return inradius;
+	}
+
+	// --- start of generated output --- //
+
+	// preperations for parameterized vertex coordinates 
+	const vertexParametriziation = false;
+	// generate the faces color by color 
+	const geometry1 = new THREE.BufferGeometry();
+	function setVertices1(){
+		var vertices1 = new Float32Array( [
+				0.951056516,0.,0.,
+			0.425325404,0.8506508085,0.,
+			0.425325404,0.262865556,0.809016994,
+
+			0.951056516,0.,0.,
+			0.425325404,0.8506508085,0.,
+			-0.0449027976,-0.0277514551,0.08541019649999999,
+
+			0.951056516,0.,0.,
+			-0.0449027976,-0.0277514551,0.08541019649999999,
+			0.425325404,-0.6881909604000001,-0.4999999998,
+
+			0.951056516,0.,0.,
+			0.425325404,-0.6881909604000001,-0.4999999998,
+			0.425325404,-0.6881909604000001,0.4999999998,
+
+			0.951056516,0.,0.,
+			0.425325404,0.262865556,0.809016994,
+			0.425325404,-0.6881909604000001,0.4999999998,
+
+			0.425325404,0.8506508085,0.,
+			0.425325404,0.262865556,0.809016994,
+			-0.425325404,0.6881909604000001,0.4999999998,
+
+			0.425325404,0.8506508085,0.,
+			-0.0449027976,-0.0277514551,0.08541019649999999,
+			-0.425325404,0.6881909604000001,-0.4999999998,
+
+			-0.0449027976,-0.0277514551,0.08541019649999999,
+			0.425325404,-0.6881909604000001,-0.4999999998,
+			-0.425325404,-0.262865556,-0.809016994,
+
+			0.425325404,-0.6881909604000001,-0.4999999998,
+			0.425325404,-0.6881909604000001,0.4999999998,
+			-0.425325404,-0.8506508085,0.,
+
+			0.425325404,0.262865556,0.809016994,
+			0.425325404,-0.6881909604000001,0.4999999998,
+			0.0449027976,0.0277514551,-0.08541019649999999,
+
+			0.425325404,0.8506508085,0.,
+			-0.425325404,0.6881909604000001,0.4999999998,
+			-0.425325404,0.6881909604000001,-0.4999999998,
+
+			-0.0449027976,-0.0277514551,0.08541019649999999,
+			-0.425325404,0.6881909604000001,-0.4999999998,
+			-0.425325404,-0.262865556,-0.809016994,
+
+			0.425325404,-0.6881909604000001,-0.4999999998,
+			-0.425325404,-0.262865556,-0.809016994,
+			-0.425325404,-0.8506508085,0.,
+
+			0.425325404,-0.6881909604000001,0.4999999998,
+			-0.425325404,-0.8506508085,0.,
+			0.0449027976,0.0277514551,-0.08541019649999999,
+
+			0.425325404,0.262865556,0.809016994,
+			-0.425325404,0.6881909604000001,0.4999999998,
+			0.0449027976,0.0277514551,-0.08541019649999999,
+
+			-0.425325404,0.6881909604000001,0.4999999998,
+			-0.425325404,0.6881909604000001,-0.4999999998,
+			-0.951056516,0.,0.,
+
+			-0.425325404,0.6881909604000001,-0.4999999998,
+			-0.425325404,-0.262865556,-0.809016994,
+			-0.951056516,0.,0.,
+
+			-0.425325404,-0.262865556,-0.809016994,
+			-0.425325404,-0.8506508085,0.,
+			-0.951056516,0.,0.,
+
+			-0.425325404,-0.8506508085,0.,
+			0.0449027976,0.0277514551,-0.08541019649999999,
+			-0.951056516,0.,0.,
+
+			-0.425325404,0.6881909604000001,0.4999999998,
+			0.0449027976,0.0277514551,-0.08541019649999999,
+			-0.951056516,0.,0.,
+
+					] ); 
+
+		return vertices1; 
+	}
+
+	geometry1.setAttribute( 'position', new THREE.BufferAttribute( setVertices1(), 3 ) );
+
+	// generate materials in the given color and normals material for the faces 
+
+    const materialNormal1 = new THREE.MeshNormalMaterial({
+        flatShading: true,
+    });
+    materialNormal1.transparent = true;
+    materialNormal1.side = THREE.DoubleSide;
+        
+    const material1 = new THREE.MeshPhongMaterial({
+        color: 0x049EF4,
+        flatShading: true,
+    });
+    material1.transparent = true;
+    material1.side = THREE.DoubleSide;
+        
+	// generate meshes for the faces from the materials with the vertex coordinates from before 
+
+    const mesh1 = new THREE.Mesh( geometry1, material1 );
+    mesh1.castShadow = true;                         
+    mesh1.receiveShadow = true;                      
+                                
+    meshRoot.add(mesh1);
+        
+    const meshNormal1 = new THREE.Mesh( geometry1, materialNormal1 );
+    mesh1.castShadow = true;                         
+    mesh1.receiveShadow = true;                      
+                                
+    normalMeshRoot.add(meshNormal1);
+        
+	// generate the edges grouped by color
+		controlFolder.remove(edgeWidthGUI);
+
+    const edgeMaterial1 = new THREE.LineBasicMaterial( {
+        color: 0x000000,
+        linewidth: 3.,
+    } );
+        
+	function getEdges1(){
+		const edges1 = new Float32Array( [
+			0.95105651599999996,0.,0.,
+			0.42532540400000002,0.85065080849999997,0.,
+
+			0.95105651599999996,0.,0.,
+			0.42532540400000002,0.262865556,0.80901699400000004,
+
+			0.95105651599999996,0.,0.,
+			-0.044902797600000002,-0.027751455099999999,0.085410196499999994,
+
+			0.95105651599999996,0.,0.,
+			0.42532540400000002,-0.68819096040000005,-0.49999999979999998,
+
+			0.95105651599999996,0.,0.,
+			0.42532540400000002,-0.68819096040000005,0.49999999979999998,
+
+			0.42532540400000002,0.85065080849999997,0.,
+			0.42532540400000002,0.262865556,0.80901699400000004,
+
+			0.42532540400000002,0.85065080849999997,0.,
+			-0.044902797600000002,-0.027751455099999999,0.085410196499999994,
+
+			0.42532540400000002,0.85065080849999997,0.,
+			-0.42532540400000002,0.68819096040000005,0.49999999979999998,
+
+			0.42532540400000002,0.85065080849999997,0.,
+			-0.42532540400000002,0.68819096040000005,-0.49999999979999998,
+
+			0.42532540400000002,0.262865556,0.80901699400000004,
+			0.42532540400000002,-0.68819096040000005,0.49999999979999998,
+
+			0.42532540400000002,0.262865556,0.80901699400000004,
+			-0.42532540400000002,0.68819096040000005,0.49999999979999998,
+
+			0.42532540400000002,0.262865556,0.80901699400000004,
+			0.044902797600000002,0.027751455099999999,-0.085410196499999994,
+
+			-0.044902797600000002,-0.027751455099999999,0.085410196499999994,
+			0.42532540400000002,-0.68819096040000005,-0.49999999979999998,
+
+			-0.044902797600000002,-0.027751455099999999,0.085410196499999994,
+			-0.42532540400000002,0.68819096040000005,-0.49999999979999998,
+
+			-0.044902797600000002,-0.027751455099999999,0.085410196499999994,
+			-0.42532540400000002,-0.262865556,-0.80901699400000004,
+
+			0.42532540400000002,-0.68819096040000005,-0.49999999979999998,
+			0.42532540400000002,-0.68819096040000005,0.49999999979999998,
+
+			0.42532540400000002,-0.68819096040000005,-0.49999999979999998,
+			-0.42532540400000002,-0.262865556,-0.80901699400000004,
+
+			0.42532540400000002,-0.68819096040000005,-0.49999999979999998,
+			-0.42532540400000002,-0.85065080849999997,0.,
+
+			0.42532540400000002,-0.68819096040000005,0.49999999979999998,
+			-0.42532540400000002,-0.85065080849999997,0.,
+
+			0.42532540400000002,-0.68819096040000005,0.49999999979999998,
+			0.044902797600000002,0.027751455099999999,-0.085410196499999994,
+
+			-0.42532540400000002,0.68819096040000005,0.49999999979999998,
+			-0.42532540400000002,0.68819096040000005,-0.49999999979999998,
+
+			-0.42532540400000002,0.68819096040000005,0.49999999979999998,
+			0.044902797600000002,0.027751455099999999,-0.085410196499999994,
+
+			-0.42532540400000002,0.68819096040000005,0.49999999979999998,
+			-0.95105651599999996,0.,0.,
+
+			-0.42532540400000002,0.68819096040000005,-0.49999999979999998,
+			-0.42532540400000002,-0.262865556,-0.80901699400000004,
+
+			-0.42532540400000002,0.68819096040000005,-0.49999999979999998,
+			-0.95105651599999996,0.,0.,
+
+			-0.42532540400000002,-0.262865556,-0.80901699400000004,
+			-0.42532540400000002,-0.85065080849999997,0.,
+
+			-0.42532540400000002,-0.262865556,-0.80901699400000004,
+			-0.95105651599999996,0.,0.,
+
+			-0.42532540400000002,-0.85065080849999997,0.,
+			0.044902797600000002,0.027751455099999999,-0.085410196499999994,
+
+			-0.42532540400000002,-0.85065080849999997,0.,
+			-0.95105651599999996,0.,0.,
+
+			0.044902797600000002,0.027751455099999999,-0.085410196499999994,
+			-0.95105651599999996,0.,0.,
+
+		]);
+		return edges1;
+	}
+
+
+	// generate geometries and lines for the edges 
+
+    const edgeGeometry1 = new THREE.BufferGeometry();
+    edgeGeometry1.setAttribute( 'position', new THREE.BufferAttribute( getEdges1(), 3 ) );
+
+    const edgeLine1 = new THREE.LineSegments( edgeGeometry1, edgeMaterial1 );
+    edgeRoot.add(edgeLine1);
+        
+	// update function to be called every frame 
+	// generate labels and spheres for the vertices
+
+
+	function getVertex1(){
+		return [0.95105651599999996,0.,0.,];
+	}
+	const sphereMaterial1 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere1 = new THREE.Mesh( sphereGeometry, sphereMaterial1 );
+	vertexRoot.add(sphere1);
+	sphere1.position.set(getVertex1()[0],getVertex1()[1],getVertex1()[2]);
+
+    const lableDiv1 = document.createElement( 'div' );
+    lableDiv1.className = 'label';
+    lableDiv1.textContent = '1';
+    lableDiv1.style.marginTop = '-1em';
+
+    const vertexLabel1 = new CSS2DObject( lableDiv1 );
+    vertexLabel1.position.set(getVertex1()[0],getVertex1()[1],getVertex1()[2]);
+    vertexlabelRoot.add( vertexLabel1 );
+            
+            
+
+	function getVertex2(){
+		return [0.42532540400000002,0.85065080849999997,0.,];
+	}
+	const sphereMaterial2 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere2 = new THREE.Mesh( sphereGeometry, sphereMaterial2 );
+	vertexRoot.add(sphere2);
+	sphere2.position.set(getVertex2()[0],getVertex2()[1],getVertex2()[2]);
+
+    const lableDiv2 = document.createElement( 'div' );
+    lableDiv2.className = 'label';
+    lableDiv2.textContent = '2';
+    lableDiv2.style.marginTop = '-1em';
+
+    const vertexLabel2 = new CSS2DObject( lableDiv2 );
+    vertexLabel2.position.set(getVertex2()[0],getVertex2()[1],getVertex2()[2]);
+    vertexlabelRoot.add( vertexLabel2 );
+            
+            
+
+	function getVertex3(){
+		return [0.42532540400000002,0.262865556,0.80901699400000004,];
+	}
+	const sphereMaterial3 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere3 = new THREE.Mesh( sphereGeometry, sphereMaterial3 );
+	vertexRoot.add(sphere3);
+	sphere3.position.set(getVertex3()[0],getVertex3()[1],getVertex3()[2]);
+
+    const lableDiv3 = document.createElement( 'div' );
+    lableDiv3.className = 'label';
+    lableDiv3.textContent = '3';
+    lableDiv3.style.marginTop = '-1em';
+
+    const vertexLabel3 = new CSS2DObject( lableDiv3 );
+    vertexLabel3.position.set(getVertex3()[0],getVertex3()[1],getVertex3()[2]);
+    vertexlabelRoot.add( vertexLabel3 );
+            
+            
+
+	function getVertex4(){
+		return [-0.044902797600000002,-0.027751455099999999,0.085410196499999994,];
+	}
+	const sphereMaterial4 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere4 = new THREE.Mesh( sphereGeometry, sphereMaterial4 );
+	vertexRoot.add(sphere4);
+	sphere4.position.set(getVertex4()[0],getVertex4()[1],getVertex4()[2]);
+
+    const lableDiv4 = document.createElement( 'div' );
+    lableDiv4.className = 'label';
+    lableDiv4.textContent = '4';
+    lableDiv4.style.marginTop = '-1em';
+
+    const vertexLabel4 = new CSS2DObject( lableDiv4 );
+    vertexLabel4.position.set(getVertex4()[0],getVertex4()[1],getVertex4()[2]);
+    vertexlabelRoot.add( vertexLabel4 );
+            
+            
+
+	function getVertex5(){
+		return [0.42532540400000002,-0.68819096040000005,-0.49999999979999998,];
+	}
+	const sphereMaterial5 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere5 = new THREE.Mesh( sphereGeometry, sphereMaterial5 );
+	vertexRoot.add(sphere5);
+	sphere5.position.set(getVertex5()[0],getVertex5()[1],getVertex5()[2]);
+
+    const lableDiv5 = document.createElement( 'div' );
+    lableDiv5.className = 'label';
+    lableDiv5.textContent = '5';
+    lableDiv5.style.marginTop = '-1em';
+
+    const vertexLabel5 = new CSS2DObject( lableDiv5 );
+    vertexLabel5.position.set(getVertex5()[0],getVertex5()[1],getVertex5()[2]);
+    vertexlabelRoot.add( vertexLabel5 );
+            
+            
+
+	function getVertex6(){
+		return [0.42532540400000002,-0.68819096040000005,0.49999999979999998,];
+	}
+	const sphereMaterial6 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere6 = new THREE.Mesh( sphereGeometry, sphereMaterial6 );
+	vertexRoot.add(sphere6);
+	sphere6.position.set(getVertex6()[0],getVertex6()[1],getVertex6()[2]);
+
+    const lableDiv6 = document.createElement( 'div' );
+    lableDiv6.className = 'label';
+    lableDiv6.textContent = '6';
+    lableDiv6.style.marginTop = '-1em';
+
+    const vertexLabel6 = new CSS2DObject( lableDiv6 );
+    vertexLabel6.position.set(getVertex6()[0],getVertex6()[1],getVertex6()[2]);
+    vertexlabelRoot.add( vertexLabel6 );
+            
+            
+
+	function getVertex7(){
+		return [-0.42532540400000002,0.68819096040000005,0.49999999979999998,];
+	}
+	const sphereMaterial7 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere7 = new THREE.Mesh( sphereGeometry, sphereMaterial7 );
+	vertexRoot.add(sphere7);
+	sphere7.position.set(getVertex7()[0],getVertex7()[1],getVertex7()[2]);
+
+    const lableDiv7 = document.createElement( 'div' );
+    lableDiv7.className = 'label';
+    lableDiv7.textContent = '7';
+    lableDiv7.style.marginTop = '-1em';
+
+    const vertexLabel7 = new CSS2DObject( lableDiv7 );
+    vertexLabel7.position.set(getVertex7()[0],getVertex7()[1],getVertex7()[2]);
+    vertexlabelRoot.add( vertexLabel7 );
+            
+            
+
+	function getVertex8(){
+		return [-0.42532540400000002,0.68819096040000005,-0.49999999979999998,];
+	}
+	const sphereMaterial8 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere8 = new THREE.Mesh( sphereGeometry, sphereMaterial8 );
+	vertexRoot.add(sphere8);
+	sphere8.position.set(getVertex8()[0],getVertex8()[1],getVertex8()[2]);
+
+    const lableDiv8 = document.createElement( 'div' );
+    lableDiv8.className = 'label';
+    lableDiv8.textContent = '8';
+    lableDiv8.style.marginTop = '-1em';
+
+    const vertexLabel8 = new CSS2DObject( lableDiv8 );
+    vertexLabel8.position.set(getVertex8()[0],getVertex8()[1],getVertex8()[2]);
+    vertexlabelRoot.add( vertexLabel8 );
+            
+            
+
+	function getVertex9(){
+		return [-0.42532540400000002,-0.262865556,-0.80901699400000004,];
+	}
+	const sphereMaterial9 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere9 = new THREE.Mesh( sphereGeometry, sphereMaterial9 );
+	vertexRoot.add(sphere9);
+	sphere9.position.set(getVertex9()[0],getVertex9()[1],getVertex9()[2]);
+
+    const lableDiv9 = document.createElement( 'div' );
+    lableDiv9.className = 'label';
+    lableDiv9.textContent = '9';
+    lableDiv9.style.marginTop = '-1em';
+
+    const vertexLabel9 = new CSS2DObject( lableDiv9 );
+    vertexLabel9.position.set(getVertex9()[0],getVertex9()[1],getVertex9()[2]);
+    vertexlabelRoot.add( vertexLabel9 );
+            
+            
+
+	function getVertex10(){
+		return [-0.42532540400000002,-0.85065080849999997,0.,];
+	}
+	const sphereMaterial10 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere10 = new THREE.Mesh( sphereGeometry, sphereMaterial10 );
+	vertexRoot.add(sphere10);
+	sphere10.position.set(getVertex10()[0],getVertex10()[1],getVertex10()[2]);
+
+    const lableDiv10 = document.createElement( 'div' );
+    lableDiv10.className = 'label';
+    lableDiv10.textContent = '10';
+    lableDiv10.style.marginTop = '-1em';
+
+    const vertexLabel10 = new CSS2DObject( lableDiv10 );
+    vertexLabel10.position.set(getVertex10()[0],getVertex10()[1],getVertex10()[2]);
+    vertexlabelRoot.add( vertexLabel10 );
+            
+            
+
+	function getVertex11(){
+		return [0.044902797600000002,0.027751455099999999,-0.085410196499999994,];
+	}
+	const sphereMaterial11 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere11 = new THREE.Mesh( sphereGeometry, sphereMaterial11 );
+	vertexRoot.add(sphere11);
+	sphere11.position.set(getVertex11()[0],getVertex11()[1],getVertex11()[2]);
+
+    const lableDiv11 = document.createElement( 'div' );
+    lableDiv11.className = 'label';
+    lableDiv11.textContent = '11';
+    lableDiv11.style.marginTop = '-1em';
+
+    const vertexLabel11 = new CSS2DObject( lableDiv11 );
+    vertexLabel11.position.set(getVertex11()[0],getVertex11()[1],getVertex11()[2]);
+    vertexlabelRoot.add( vertexLabel11 );
+            
+            
+
+	function getVertex12(){
+		return [-0.95105651599999996,0.,0.,];
+	}
+	const sphereMaterial12 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere12 = new THREE.Mesh( sphereGeometry, sphereMaterial12 );
+	vertexRoot.add(sphere12);
+	sphere12.position.set(getVertex12()[0],getVertex12()[1],getVertex12()[2]);
+
+    const lableDiv12 = document.createElement( 'div' );
+    lableDiv12.className = 'label';
+    lableDiv12.textContent = '12';
+    lableDiv12.style.marginTop = '-1em';
+
+    const vertexLabel12 = new CSS2DObject( lableDiv12 );
+    vertexLabel12.position.set(getVertex12()[0],getVertex12()[1],getVertex12()[2]);
+    vertexlabelRoot.add( vertexLabel12 );
+            
+            	// generate the rings for the incircles 
+
+	var inradius1 = calulateInradius(getVertex1(), getVertex2(), getVertex3());
+	var incenter1 = calulateIncenter(getVertex1(), getVertex2(), getVertex3());
+	var ringGeometry1 = new THREE.RingGeometry((inradius1 - 0.005),inradius1, 32);
+	const ringMaterial1 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh1 = new THREE.Mesh(ringGeometry1, ringMaterial1);
+
+	function setCircleRotation1(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.95105651599999996,0.,0.],[ 0.42532540400000002,0.85065080849999997,0.],[0.42532540400000002,0.262865556,0.80901699400000004]);
+
+        ringMesh1.position.setX(incenter[0]);
+        ringMesh1.position.setY(incenter[1]);
+        ringMesh1.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex1(), getVertex2(), getVertex3());
+        var relRadius = inradius/inradius1;
+
+        ringMesh1.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A1 = new THREE.Vector3(0.95105651599999996,0.,0.);
+        const B1 = new THREE.Vector3(0.42532540400000002,0.85065080849999997,0.);
+        const C1 = new THREE.Vector3(0.42532540400000002,0.262865556,0.80901699400000004);
+
+        const normalVec1 = new THREE.Vector3();
+        normalVec1.crossVectors(B1.sub(A1), C1.sub(A1));
+        normalVec1.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal1 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation1 = new THREE.Quaternion();
+        quaternionRotation1.setFromUnitVectors(initialNormal1, normalVec1);
+
+        ringMesh1.setRotationFromQuaternion(quaternionRotation1);
+
+        return quaternionRotation1;
+    }
+
+    ringRoot.add(ringMesh1);
+            
+	var inradius2 = calulateInradius(getVertex1(), getVertex2(), getVertex4());
+	var incenter2 = calulateIncenter(getVertex1(), getVertex2(), getVertex4());
+	var ringGeometry2 = new THREE.RingGeometry((inradius2 - 0.005),inradius2, 32);
+	const ringMaterial2 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh2 = new THREE.Mesh(ringGeometry2, ringMaterial2);
+
+	function setCircleRotation2(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.95105651599999996,0.,0.],[ 0.42532540400000002,0.85065080849999997,0.],[-0.044902797600000002,-0.027751455099999999,0.085410196499999994]);
+
+        ringMesh2.position.setX(incenter[0]);
+        ringMesh2.position.setY(incenter[1]);
+        ringMesh2.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex1(), getVertex2(), getVertex4());
+        var relRadius = inradius/inradius2;
+
+        ringMesh2.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A2 = new THREE.Vector3(0.95105651599999996,0.,0.);
+        const B2 = new THREE.Vector3(0.42532540400000002,0.85065080849999997,0.);
+        const C2 = new THREE.Vector3(-0.044902797600000002,-0.027751455099999999,0.085410196499999994);
+
+        const normalVec2 = new THREE.Vector3();
+        normalVec2.crossVectors(B2.sub(A2), C2.sub(A2));
+        normalVec2.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal2 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation2 = new THREE.Quaternion();
+        quaternionRotation2.setFromUnitVectors(initialNormal2, normalVec2);
+
+        ringMesh2.setRotationFromQuaternion(quaternionRotation2);
+
+        return quaternionRotation2;
+    }
+
+    ringRoot.add(ringMesh2);
+            
+	var inradius3 = calulateInradius(getVertex1(), getVertex4(), getVertex5());
+	var incenter3 = calulateIncenter(getVertex1(), getVertex4(), getVertex5());
+	var ringGeometry3 = new THREE.RingGeometry((inradius3 - 0.005),inradius3, 32);
+	const ringMaterial3 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh3 = new THREE.Mesh(ringGeometry3, ringMaterial3);
+
+	function setCircleRotation3(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.95105651599999996,0.,0.],[ -0.044902797600000002,-0.027751455099999999,0.085410196499999994],[0.42532540400000002,-0.68819096040000005,-0.49999999979999998]);
+
+        ringMesh3.position.setX(incenter[0]);
+        ringMesh3.position.setY(incenter[1]);
+        ringMesh3.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex1(), getVertex4(), getVertex5());
+        var relRadius = inradius/inradius3;
+
+        ringMesh3.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A3 = new THREE.Vector3(0.95105651599999996,0.,0.);
+        const B3 = new THREE.Vector3(-0.044902797600000002,-0.027751455099999999,0.085410196499999994);
+        const C3 = new THREE.Vector3(0.42532540400000002,-0.68819096040000005,-0.49999999979999998);
+
+        const normalVec3 = new THREE.Vector3();
+        normalVec3.crossVectors(B3.sub(A3), C3.sub(A3));
+        normalVec3.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal3 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation3 = new THREE.Quaternion();
+        quaternionRotation3.setFromUnitVectors(initialNormal3, normalVec3);
+
+        ringMesh3.setRotationFromQuaternion(quaternionRotation3);
+
+        return quaternionRotation3;
+    }
+
+    ringRoot.add(ringMesh3);
+            
+	var inradius4 = calulateInradius(getVertex1(), getVertex5(), getVertex6());
+	var incenter4 = calulateIncenter(getVertex1(), getVertex5(), getVertex6());
+	var ringGeometry4 = new THREE.RingGeometry((inradius4 - 0.005),inradius4, 32);
+	const ringMaterial4 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh4 = new THREE.Mesh(ringGeometry4, ringMaterial4);
+
+	function setCircleRotation4(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.95105651599999996,0.,0.],[ 0.42532540400000002,-0.68819096040000005,-0.49999999979999998],[0.42532540400000002,-0.68819096040000005,0.49999999979999998]);
+
+        ringMesh4.position.setX(incenter[0]);
+        ringMesh4.position.setY(incenter[1]);
+        ringMesh4.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex1(), getVertex5(), getVertex6());
+        var relRadius = inradius/inradius4;
+
+        ringMesh4.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A4 = new THREE.Vector3(0.95105651599999996,0.,0.);
+        const B4 = new THREE.Vector3(0.42532540400000002,-0.68819096040000005,-0.49999999979999998);
+        const C4 = new THREE.Vector3(0.42532540400000002,-0.68819096040000005,0.49999999979999998);
+
+        const normalVec4 = new THREE.Vector3();
+        normalVec4.crossVectors(B4.sub(A4), C4.sub(A4));
+        normalVec4.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal4 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation4 = new THREE.Quaternion();
+        quaternionRotation4.setFromUnitVectors(initialNormal4, normalVec4);
+
+        ringMesh4.setRotationFromQuaternion(quaternionRotation4);
+
+        return quaternionRotation4;
+    }
+
+    ringRoot.add(ringMesh4);
+            
+	var inradius5 = calulateInradius(getVertex1(), getVertex3(), getVertex6());
+	var incenter5 = calulateIncenter(getVertex1(), getVertex3(), getVertex6());
+	var ringGeometry5 = new THREE.RingGeometry((inradius5 - 0.005),inradius5, 32);
+	const ringMaterial5 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh5 = new THREE.Mesh(ringGeometry5, ringMaterial5);
+
+	function setCircleRotation5(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.95105651599999996,0.,0.],[ 0.42532540400000002,0.262865556,0.80901699400000004],[0.42532540400000002,-0.68819096040000005,0.49999999979999998]);
+
+        ringMesh5.position.setX(incenter[0]);
+        ringMesh5.position.setY(incenter[1]);
+        ringMesh5.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex1(), getVertex3(), getVertex6());
+        var relRadius = inradius/inradius5;
+
+        ringMesh5.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A5 = new THREE.Vector3(0.95105651599999996,0.,0.);
+        const B5 = new THREE.Vector3(0.42532540400000002,0.262865556,0.80901699400000004);
+        const C5 = new THREE.Vector3(0.42532540400000002,-0.68819096040000005,0.49999999979999998);
+
+        const normalVec5 = new THREE.Vector3();
+        normalVec5.crossVectors(B5.sub(A5), C5.sub(A5));
+        normalVec5.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal5 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation5 = new THREE.Quaternion();
+        quaternionRotation5.setFromUnitVectors(initialNormal5, normalVec5);
+
+        ringMesh5.setRotationFromQuaternion(quaternionRotation5);
+
+        return quaternionRotation5;
+    }
+
+    ringRoot.add(ringMesh5);
+            
+	var inradius6 = calulateInradius(getVertex2(), getVertex3(), getVertex7());
+	var incenter6 = calulateIncenter(getVertex2(), getVertex3(), getVertex7());
+	var ringGeometry6 = new THREE.RingGeometry((inradius6 - 0.005),inradius6, 32);
+	const ringMaterial6 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh6 = new THREE.Mesh(ringGeometry6, ringMaterial6);
+
+	function setCircleRotation6(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.42532540400000002,0.85065080849999997,0.],[ 0.42532540400000002,0.262865556,0.80901699400000004],[-0.42532540400000002,0.68819096040000005,0.49999999979999998]);
+
+        ringMesh6.position.setX(incenter[0]);
+        ringMesh6.position.setY(incenter[1]);
+        ringMesh6.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex2(), getVertex3(), getVertex7());
+        var relRadius = inradius/inradius6;
+
+        ringMesh6.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A6 = new THREE.Vector3(0.42532540400000002,0.85065080849999997,0.);
+        const B6 = new THREE.Vector3(0.42532540400000002,0.262865556,0.80901699400000004);
+        const C6 = new THREE.Vector3(-0.42532540400000002,0.68819096040000005,0.49999999979999998);
+
+        const normalVec6 = new THREE.Vector3();
+        normalVec6.crossVectors(B6.sub(A6), C6.sub(A6));
+        normalVec6.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal6 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation6 = new THREE.Quaternion();
+        quaternionRotation6.setFromUnitVectors(initialNormal6, normalVec6);
+
+        ringMesh6.setRotationFromQuaternion(quaternionRotation6);
+
+        return quaternionRotation6;
+    }
+
+    ringRoot.add(ringMesh6);
+            
+	var inradius7 = calulateInradius(getVertex2(), getVertex4(), getVertex8());
+	var incenter7 = calulateIncenter(getVertex2(), getVertex4(), getVertex8());
+	var ringGeometry7 = new THREE.RingGeometry((inradius7 - 0.005),inradius7, 32);
+	const ringMaterial7 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh7 = new THREE.Mesh(ringGeometry7, ringMaterial7);
+
+	function setCircleRotation7(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.42532540400000002,0.85065080849999997,0.],[ -0.044902797600000002,-0.027751455099999999,0.085410196499999994],[-0.42532540400000002,0.68819096040000005,-0.49999999979999998]);
+
+        ringMesh7.position.setX(incenter[0]);
+        ringMesh7.position.setY(incenter[1]);
+        ringMesh7.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex2(), getVertex4(), getVertex8());
+        var relRadius = inradius/inradius7;
+
+        ringMesh7.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A7 = new THREE.Vector3(0.42532540400000002,0.85065080849999997,0.);
+        const B7 = new THREE.Vector3(-0.044902797600000002,-0.027751455099999999,0.085410196499999994);
+        const C7 = new THREE.Vector3(-0.42532540400000002,0.68819096040000005,-0.49999999979999998);
+
+        const normalVec7 = new THREE.Vector3();
+        normalVec7.crossVectors(B7.sub(A7), C7.sub(A7));
+        normalVec7.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal7 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation7 = new THREE.Quaternion();
+        quaternionRotation7.setFromUnitVectors(initialNormal7, normalVec7);
+
+        ringMesh7.setRotationFromQuaternion(quaternionRotation7);
+
+        return quaternionRotation7;
+    }
+
+    ringRoot.add(ringMesh7);
+            
+	var inradius8 = calulateInradius(getVertex4(), getVertex5(), getVertex9());
+	var incenter8 = calulateIncenter(getVertex4(), getVertex5(), getVertex9());
+	var ringGeometry8 = new THREE.RingGeometry((inradius8 - 0.005),inradius8, 32);
+	const ringMaterial8 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh8 = new THREE.Mesh(ringGeometry8, ringMaterial8);
+
+	function setCircleRotation8(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([-0.044902797600000002,-0.027751455099999999,0.085410196499999994],[ 0.42532540400000002,-0.68819096040000005,-0.49999999979999998],[-0.42532540400000002,-0.262865556,-0.80901699400000004]);
+
+        ringMesh8.position.setX(incenter[0]);
+        ringMesh8.position.setY(incenter[1]);
+        ringMesh8.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex4(), getVertex5(), getVertex9());
+        var relRadius = inradius/inradius8;
+
+        ringMesh8.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A8 = new THREE.Vector3(-0.044902797600000002,-0.027751455099999999,0.085410196499999994);
+        const B8 = new THREE.Vector3(0.42532540400000002,-0.68819096040000005,-0.49999999979999998);
+        const C8 = new THREE.Vector3(-0.42532540400000002,-0.262865556,-0.80901699400000004);
+
+        const normalVec8 = new THREE.Vector3();
+        normalVec8.crossVectors(B8.sub(A8), C8.sub(A8));
+        normalVec8.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal8 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation8 = new THREE.Quaternion();
+        quaternionRotation8.setFromUnitVectors(initialNormal8, normalVec8);
+
+        ringMesh8.setRotationFromQuaternion(quaternionRotation8);
+
+        return quaternionRotation8;
+    }
+
+    ringRoot.add(ringMesh8);
+            
+	var inradius9 = calulateInradius(getVertex5(), getVertex6(), getVertex10());
+	var incenter9 = calulateIncenter(getVertex5(), getVertex6(), getVertex10());
+	var ringGeometry9 = new THREE.RingGeometry((inradius9 - 0.005),inradius9, 32);
+	const ringMaterial9 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh9 = new THREE.Mesh(ringGeometry9, ringMaterial9);
+
+	function setCircleRotation9(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.42532540400000002,-0.68819096040000005,-0.49999999979999998],[ 0.42532540400000002,-0.68819096040000005,0.49999999979999998],[-0.42532540400000002,-0.85065080849999997,0.]);
+
+        ringMesh9.position.setX(incenter[0]);
+        ringMesh9.position.setY(incenter[1]);
+        ringMesh9.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex5(), getVertex6(), getVertex10());
+        var relRadius = inradius/inradius9;
+
+        ringMesh9.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A9 = new THREE.Vector3(0.42532540400000002,-0.68819096040000005,-0.49999999979999998);
+        const B9 = new THREE.Vector3(0.42532540400000002,-0.68819096040000005,0.49999999979999998);
+        const C9 = new THREE.Vector3(-0.42532540400000002,-0.85065080849999997,0.);
+
+        const normalVec9 = new THREE.Vector3();
+        normalVec9.crossVectors(B9.sub(A9), C9.sub(A9));
+        normalVec9.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal9 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation9 = new THREE.Quaternion();
+        quaternionRotation9.setFromUnitVectors(initialNormal9, normalVec9);
+
+        ringMesh9.setRotationFromQuaternion(quaternionRotation9);
+
+        return quaternionRotation9;
+    }
+
+    ringRoot.add(ringMesh9);
+            
+	var inradius10 = calulateInradius(getVertex3(), getVertex6(), getVertex11());
+	var incenter10 = calulateIncenter(getVertex3(), getVertex6(), getVertex11());
+	var ringGeometry10 = new THREE.RingGeometry((inradius10 - 0.005),inradius10, 32);
+	const ringMaterial10 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh10 = new THREE.Mesh(ringGeometry10, ringMaterial10);
+
+	function setCircleRotation10(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.42532540400000002,0.262865556,0.80901699400000004],[ 0.42532540400000002,-0.68819096040000005,0.49999999979999998],[0.044902797600000002,0.027751455099999999,-0.085410196499999994]);
+
+        ringMesh10.position.setX(incenter[0]);
+        ringMesh10.position.setY(incenter[1]);
+        ringMesh10.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex3(), getVertex6(), getVertex11());
+        var relRadius = inradius/inradius10;
+
+        ringMesh10.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A10 = new THREE.Vector3(0.42532540400000002,0.262865556,0.80901699400000004);
+        const B10 = new THREE.Vector3(0.42532540400000002,-0.68819096040000005,0.49999999979999998);
+        const C10 = new THREE.Vector3(0.044902797600000002,0.027751455099999999,-0.085410196499999994);
+
+        const normalVec10 = new THREE.Vector3();
+        normalVec10.crossVectors(B10.sub(A10), C10.sub(A10));
+        normalVec10.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal10 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation10 = new THREE.Quaternion();
+        quaternionRotation10.setFromUnitVectors(initialNormal10, normalVec10);
+
+        ringMesh10.setRotationFromQuaternion(quaternionRotation10);
+
+        return quaternionRotation10;
+    }
+
+    ringRoot.add(ringMesh10);
+            
+	var inradius11 = calulateInradius(getVertex2(), getVertex7(), getVertex8());
+	var incenter11 = calulateIncenter(getVertex2(), getVertex7(), getVertex8());
+	var ringGeometry11 = new THREE.RingGeometry((inradius11 - 0.005),inradius11, 32);
+	const ringMaterial11 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh11 = new THREE.Mesh(ringGeometry11, ringMaterial11);
+
+	function setCircleRotation11(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.42532540400000002,0.85065080849999997,0.],[ -0.42532540400000002,0.68819096040000005,0.49999999979999998],[-0.42532540400000002,0.68819096040000005,-0.49999999979999998]);
+
+        ringMesh11.position.setX(incenter[0]);
+        ringMesh11.position.setY(incenter[1]);
+        ringMesh11.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex2(), getVertex7(), getVertex8());
+        var relRadius = inradius/inradius11;
+
+        ringMesh11.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A11 = new THREE.Vector3(0.42532540400000002,0.85065080849999997,0.);
+        const B11 = new THREE.Vector3(-0.42532540400000002,0.68819096040000005,0.49999999979999998);
+        const C11 = new THREE.Vector3(-0.42532540400000002,0.68819096040000005,-0.49999999979999998);
+
+        const normalVec11 = new THREE.Vector3();
+        normalVec11.crossVectors(B11.sub(A11), C11.sub(A11));
+        normalVec11.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal11 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation11 = new THREE.Quaternion();
+        quaternionRotation11.setFromUnitVectors(initialNormal11, normalVec11);
+
+        ringMesh11.setRotationFromQuaternion(quaternionRotation11);
+
+        return quaternionRotation11;
+    }
+
+    ringRoot.add(ringMesh11);
+            
+	var inradius12 = calulateInradius(getVertex4(), getVertex8(), getVertex9());
+	var incenter12 = calulateIncenter(getVertex4(), getVertex8(), getVertex9());
+	var ringGeometry12 = new THREE.RingGeometry((inradius12 - 0.005),inradius12, 32);
+	const ringMaterial12 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh12 = new THREE.Mesh(ringGeometry12, ringMaterial12);
+
+	function setCircleRotation12(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([-0.044902797600000002,-0.027751455099999999,0.085410196499999994],[ -0.42532540400000002,0.68819096040000005,-0.49999999979999998],[-0.42532540400000002,-0.262865556,-0.80901699400000004]);
+
+        ringMesh12.position.setX(incenter[0]);
+        ringMesh12.position.setY(incenter[1]);
+        ringMesh12.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex4(), getVertex8(), getVertex9());
+        var relRadius = inradius/inradius12;
+
+        ringMesh12.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A12 = new THREE.Vector3(-0.044902797600000002,-0.027751455099999999,0.085410196499999994);
+        const B12 = new THREE.Vector3(-0.42532540400000002,0.68819096040000005,-0.49999999979999998);
+        const C12 = new THREE.Vector3(-0.42532540400000002,-0.262865556,-0.80901699400000004);
+
+        const normalVec12 = new THREE.Vector3();
+        normalVec12.crossVectors(B12.sub(A12), C12.sub(A12));
+        normalVec12.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal12 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation12 = new THREE.Quaternion();
+        quaternionRotation12.setFromUnitVectors(initialNormal12, normalVec12);
+
+        ringMesh12.setRotationFromQuaternion(quaternionRotation12);
+
+        return quaternionRotation12;
+    }
+
+    ringRoot.add(ringMesh12);
+            
+	var inradius13 = calulateInradius(getVertex5(), getVertex9(), getVertex10());
+	var incenter13 = calulateIncenter(getVertex5(), getVertex9(), getVertex10());
+	var ringGeometry13 = new THREE.RingGeometry((inradius13 - 0.005),inradius13, 32);
+	const ringMaterial13 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh13 = new THREE.Mesh(ringGeometry13, ringMaterial13);
+
+	function setCircleRotation13(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.42532540400000002,-0.68819096040000005,-0.49999999979999998],[ -0.42532540400000002,-0.262865556,-0.80901699400000004],[-0.42532540400000002,-0.85065080849999997,0.]);
+
+        ringMesh13.position.setX(incenter[0]);
+        ringMesh13.position.setY(incenter[1]);
+        ringMesh13.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex5(), getVertex9(), getVertex10());
+        var relRadius = inradius/inradius13;
+
+        ringMesh13.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A13 = new THREE.Vector3(0.42532540400000002,-0.68819096040000005,-0.49999999979999998);
+        const B13 = new THREE.Vector3(-0.42532540400000002,-0.262865556,-0.80901699400000004);
+        const C13 = new THREE.Vector3(-0.42532540400000002,-0.85065080849999997,0.);
+
+        const normalVec13 = new THREE.Vector3();
+        normalVec13.crossVectors(B13.sub(A13), C13.sub(A13));
+        normalVec13.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal13 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation13 = new THREE.Quaternion();
+        quaternionRotation13.setFromUnitVectors(initialNormal13, normalVec13);
+
+        ringMesh13.setRotationFromQuaternion(quaternionRotation13);
+
+        return quaternionRotation13;
+    }
+
+    ringRoot.add(ringMesh13);
+            
+	var inradius14 = calulateInradius(getVertex6(), getVertex10(), getVertex11());
+	var incenter14 = calulateIncenter(getVertex6(), getVertex10(), getVertex11());
+	var ringGeometry14 = new THREE.RingGeometry((inradius14 - 0.005),inradius14, 32);
+	const ringMaterial14 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh14 = new THREE.Mesh(ringGeometry14, ringMaterial14);
+
+	function setCircleRotation14(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.42532540400000002,-0.68819096040000005,0.49999999979999998],[ -0.42532540400000002,-0.85065080849999997,0.],[0.044902797600000002,0.027751455099999999,-0.085410196499999994]);
+
+        ringMesh14.position.setX(incenter[0]);
+        ringMesh14.position.setY(incenter[1]);
+        ringMesh14.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex6(), getVertex10(), getVertex11());
+        var relRadius = inradius/inradius14;
+
+        ringMesh14.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A14 = new THREE.Vector3(0.42532540400000002,-0.68819096040000005,0.49999999979999998);
+        const B14 = new THREE.Vector3(-0.42532540400000002,-0.85065080849999997,0.);
+        const C14 = new THREE.Vector3(0.044902797600000002,0.027751455099999999,-0.085410196499999994);
+
+        const normalVec14 = new THREE.Vector3();
+        normalVec14.crossVectors(B14.sub(A14), C14.sub(A14));
+        normalVec14.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal14 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation14 = new THREE.Quaternion();
+        quaternionRotation14.setFromUnitVectors(initialNormal14, normalVec14);
+
+        ringMesh14.setRotationFromQuaternion(quaternionRotation14);
+
+        return quaternionRotation14;
+    }
+
+    ringRoot.add(ringMesh14);
+            
+	var inradius15 = calulateInradius(getVertex3(), getVertex7(), getVertex11());
+	var incenter15 = calulateIncenter(getVertex3(), getVertex7(), getVertex11());
+	var ringGeometry15 = new THREE.RingGeometry((inradius15 - 0.005),inradius15, 32);
+	const ringMaterial15 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh15 = new THREE.Mesh(ringGeometry15, ringMaterial15);
+
+	function setCircleRotation15(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.42532540400000002,0.262865556,0.80901699400000004],[ -0.42532540400000002,0.68819096040000005,0.49999999979999998],[0.044902797600000002,0.027751455099999999,-0.085410196499999994]);
+
+        ringMesh15.position.setX(incenter[0]);
+        ringMesh15.position.setY(incenter[1]);
+        ringMesh15.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex3(), getVertex7(), getVertex11());
+        var relRadius = inradius/inradius15;
+
+        ringMesh15.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A15 = new THREE.Vector3(0.42532540400000002,0.262865556,0.80901699400000004);
+        const B15 = new THREE.Vector3(-0.42532540400000002,0.68819096040000005,0.49999999979999998);
+        const C15 = new THREE.Vector3(0.044902797600000002,0.027751455099999999,-0.085410196499999994);
+
+        const normalVec15 = new THREE.Vector3();
+        normalVec15.crossVectors(B15.sub(A15), C15.sub(A15));
+        normalVec15.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal15 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation15 = new THREE.Quaternion();
+        quaternionRotation15.setFromUnitVectors(initialNormal15, normalVec15);
+
+        ringMesh15.setRotationFromQuaternion(quaternionRotation15);
+
+        return quaternionRotation15;
+    }
+
+    ringRoot.add(ringMesh15);
+            
+	var inradius16 = calulateInradius(getVertex7(), getVertex8(), getVertex12());
+	var incenter16 = calulateIncenter(getVertex7(), getVertex8(), getVertex12());
+	var ringGeometry16 = new THREE.RingGeometry((inradius16 - 0.005),inradius16, 32);
+	const ringMaterial16 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh16 = new THREE.Mesh(ringGeometry16, ringMaterial16);
+
+	function setCircleRotation16(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([-0.42532540400000002,0.68819096040000005,0.49999999979999998],[ -0.42532540400000002,0.68819096040000005,-0.49999999979999998],[-0.95105651599999996,0.,0.]);
+
+        ringMesh16.position.setX(incenter[0]);
+        ringMesh16.position.setY(incenter[1]);
+        ringMesh16.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex7(), getVertex8(), getVertex12());
+        var relRadius = inradius/inradius16;
+
+        ringMesh16.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A16 = new THREE.Vector3(-0.42532540400000002,0.68819096040000005,0.49999999979999998);
+        const B16 = new THREE.Vector3(-0.42532540400000002,0.68819096040000005,-0.49999999979999998);
+        const C16 = new THREE.Vector3(-0.95105651599999996,0.,0.);
+
+        const normalVec16 = new THREE.Vector3();
+        normalVec16.crossVectors(B16.sub(A16), C16.sub(A16));
+        normalVec16.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal16 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation16 = new THREE.Quaternion();
+        quaternionRotation16.setFromUnitVectors(initialNormal16, normalVec16);
+
+        ringMesh16.setRotationFromQuaternion(quaternionRotation16);
+
+        return quaternionRotation16;
+    }
+
+    ringRoot.add(ringMesh16);
+            
+	var inradius17 = calulateInradius(getVertex8(), getVertex9(), getVertex12());
+	var incenter17 = calulateIncenter(getVertex8(), getVertex9(), getVertex12());
+	var ringGeometry17 = new THREE.RingGeometry((inradius17 - 0.005),inradius17, 32);
+	const ringMaterial17 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh17 = new THREE.Mesh(ringGeometry17, ringMaterial17);
+
+	function setCircleRotation17(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([-0.42532540400000002,0.68819096040000005,-0.49999999979999998],[ -0.42532540400000002,-0.262865556,-0.80901699400000004],[-0.95105651599999996,0.,0.]);
+
+        ringMesh17.position.setX(incenter[0]);
+        ringMesh17.position.setY(incenter[1]);
+        ringMesh17.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex8(), getVertex9(), getVertex12());
+        var relRadius = inradius/inradius17;
+
+        ringMesh17.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A17 = new THREE.Vector3(-0.42532540400000002,0.68819096040000005,-0.49999999979999998);
+        const B17 = new THREE.Vector3(-0.42532540400000002,-0.262865556,-0.80901699400000004);
+        const C17 = new THREE.Vector3(-0.95105651599999996,0.,0.);
+
+        const normalVec17 = new THREE.Vector3();
+        normalVec17.crossVectors(B17.sub(A17), C17.sub(A17));
+        normalVec17.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal17 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation17 = new THREE.Quaternion();
+        quaternionRotation17.setFromUnitVectors(initialNormal17, normalVec17);
+
+        ringMesh17.setRotationFromQuaternion(quaternionRotation17);
+
+        return quaternionRotation17;
+    }
+
+    ringRoot.add(ringMesh17);
+            
+	var inradius18 = calulateInradius(getVertex9(), getVertex10(), getVertex12());
+	var incenter18 = calulateIncenter(getVertex9(), getVertex10(), getVertex12());
+	var ringGeometry18 = new THREE.RingGeometry((inradius18 - 0.005),inradius18, 32);
+	const ringMaterial18 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh18 = new THREE.Mesh(ringGeometry18, ringMaterial18);
+
+	function setCircleRotation18(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([-0.42532540400000002,-0.262865556,-0.80901699400000004],[ -0.42532540400000002,-0.85065080849999997,0.],[-0.95105651599999996,0.,0.]);
+
+        ringMesh18.position.setX(incenter[0]);
+        ringMesh18.position.setY(incenter[1]);
+        ringMesh18.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex9(), getVertex10(), getVertex12());
+        var relRadius = inradius/inradius18;
+
+        ringMesh18.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A18 = new THREE.Vector3(-0.42532540400000002,-0.262865556,-0.80901699400000004);
+        const B18 = new THREE.Vector3(-0.42532540400000002,-0.85065080849999997,0.);
+        const C18 = new THREE.Vector3(-0.95105651599999996,0.,0.);
+
+        const normalVec18 = new THREE.Vector3();
+        normalVec18.crossVectors(B18.sub(A18), C18.sub(A18));
+        normalVec18.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal18 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation18 = new THREE.Quaternion();
+        quaternionRotation18.setFromUnitVectors(initialNormal18, normalVec18);
+
+        ringMesh18.setRotationFromQuaternion(quaternionRotation18);
+
+        return quaternionRotation18;
+    }
+
+    ringRoot.add(ringMesh18);
+            
+	var inradius19 = calulateInradius(getVertex10(), getVertex11(), getVertex12());
+	var incenter19 = calulateIncenter(getVertex10(), getVertex11(), getVertex12());
+	var ringGeometry19 = new THREE.RingGeometry((inradius19 - 0.005),inradius19, 32);
+	const ringMaterial19 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh19 = new THREE.Mesh(ringGeometry19, ringMaterial19);
+
+	function setCircleRotation19(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([-0.42532540400000002,-0.85065080849999997,0.],[ 0.044902797600000002,0.027751455099999999,-0.085410196499999994],[-0.95105651599999996,0.,0.]);
+
+        ringMesh19.position.setX(incenter[0]);
+        ringMesh19.position.setY(incenter[1]);
+        ringMesh19.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex10(), getVertex11(), getVertex12());
+        var relRadius = inradius/inradius19;
+
+        ringMesh19.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A19 = new THREE.Vector3(-0.42532540400000002,-0.85065080849999997,0.);
+        const B19 = new THREE.Vector3(0.044902797600000002,0.027751455099999999,-0.085410196499999994);
+        const C19 = new THREE.Vector3(-0.95105651599999996,0.,0.);
+
+        const normalVec19 = new THREE.Vector3();
+        normalVec19.crossVectors(B19.sub(A19), C19.sub(A19));
+        normalVec19.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal19 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation19 = new THREE.Quaternion();
+        quaternionRotation19.setFromUnitVectors(initialNormal19, normalVec19);
+
+        ringMesh19.setRotationFromQuaternion(quaternionRotation19);
+
+        return quaternionRotation19;
+    }
+
+    ringRoot.add(ringMesh19);
+            
+	var inradius20 = calulateInradius(getVertex7(), getVertex11(), getVertex12());
+	var incenter20 = calulateIncenter(getVertex7(), getVertex11(), getVertex12());
+	var ringGeometry20 = new THREE.RingGeometry((inradius20 - 0.005),inradius20, 32);
+	const ringMaterial20 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh20 = new THREE.Mesh(ringGeometry20, ringMaterial20);
+
+	function setCircleRotation20(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([-0.42532540400000002,0.68819096040000005,0.49999999979999998],[ 0.044902797600000002,0.027751455099999999,-0.085410196499999994],[-0.95105651599999996,0.,0.]);
+
+        ringMesh20.position.setX(incenter[0]);
+        ringMesh20.position.setY(incenter[1]);
+        ringMesh20.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex7(), getVertex11(), getVertex12());
+        var relRadius = inradius/inradius20;
+
+        ringMesh20.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A20 = new THREE.Vector3(-0.42532540400000002,0.68819096040000005,0.49999999979999998);
+        const B20 = new THREE.Vector3(0.044902797600000002,0.027751455099999999,-0.085410196499999994);
+        const C20 = new THREE.Vector3(-0.95105651599999996,0.,0.);
+
+        const normalVec20 = new THREE.Vector3();
+        normalVec20.crossVectors(B20.sub(A20), C20.sub(A20));
+        normalVec20.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal20 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation20 = new THREE.Quaternion();
+        quaternionRotation20.setFromUnitVectors(initialNormal20, normalVec20);
+
+        ringMesh20.setRotationFromQuaternion(quaternionRotation20);
+
+        return quaternionRotation20;
+    }
+
+    ringRoot.add(ringMesh20);
+            	// function to update the circles every frame 
+	function updateCircles(){
+		setCircleRotation1();
+		setCircleRotation2();
+		setCircleRotation3();
+		setCircleRotation4();
+		setCircleRotation5();
+		setCircleRotation6();
+		setCircleRotation7();
+		setCircleRotation8();
+		setCircleRotation9();
+		setCircleRotation10();
+		setCircleRotation11();
+		setCircleRotation12();
+		setCircleRotation13();
+		setCircleRotation14();
+		setCircleRotation15();
+		setCircleRotation16();
+		setCircleRotation17();
+		setCircleRotation18();
+		setCircleRotation19();
+		setCircleRotation20();
+	}
+
+	// needs to be called once to be initialized 
+	updateCircles();
+
+	// function to update the circles width, that is called every frame even if the surface is not parameterized 
+	function updateCircleWidth(){
+		ringGeometry1.dispose();
+		ringGeometry1 = new THREE.RingGeometry((inradius1 - guiParameters.circleWidth),inradius1, 32);
+		ringMesh1.geometry = ringGeometry1; 
+		ringGeometry2.dispose();
+		ringGeometry2 = new THREE.RingGeometry((inradius2 - guiParameters.circleWidth),inradius2, 32);
+		ringMesh2.geometry = ringGeometry2; 
+		ringGeometry3.dispose();
+		ringGeometry3 = new THREE.RingGeometry((inradius3 - guiParameters.circleWidth),inradius3, 32);
+		ringMesh3.geometry = ringGeometry3; 
+		ringGeometry4.dispose();
+		ringGeometry4 = new THREE.RingGeometry((inradius4 - guiParameters.circleWidth),inradius4, 32);
+		ringMesh4.geometry = ringGeometry4; 
+		ringGeometry5.dispose();
+		ringGeometry5 = new THREE.RingGeometry((inradius5 - guiParameters.circleWidth),inradius5, 32);
+		ringMesh5.geometry = ringGeometry5; 
+		ringGeometry6.dispose();
+		ringGeometry6 = new THREE.RingGeometry((inradius6 - guiParameters.circleWidth),inradius6, 32);
+		ringMesh6.geometry = ringGeometry6; 
+		ringGeometry7.dispose();
+		ringGeometry7 = new THREE.RingGeometry((inradius7 - guiParameters.circleWidth),inradius7, 32);
+		ringMesh7.geometry = ringGeometry7; 
+		ringGeometry8.dispose();
+		ringGeometry8 = new THREE.RingGeometry((inradius8 - guiParameters.circleWidth),inradius8, 32);
+		ringMesh8.geometry = ringGeometry8; 
+		ringGeometry9.dispose();
+		ringGeometry9 = new THREE.RingGeometry((inradius9 - guiParameters.circleWidth),inradius9, 32);
+		ringMesh9.geometry = ringGeometry9; 
+		ringGeometry10.dispose();
+		ringGeometry10 = new THREE.RingGeometry((inradius10 - guiParameters.circleWidth),inradius10, 32);
+		ringMesh10.geometry = ringGeometry10; 
+		ringGeometry11.dispose();
+		ringGeometry11 = new THREE.RingGeometry((inradius11 - guiParameters.circleWidth),inradius11, 32);
+		ringMesh11.geometry = ringGeometry11; 
+		ringGeometry12.dispose();
+		ringGeometry12 = new THREE.RingGeometry((inradius12 - guiParameters.circleWidth),inradius12, 32);
+		ringMesh12.geometry = ringGeometry12; 
+		ringGeometry13.dispose();
+		ringGeometry13 = new THREE.RingGeometry((inradius13 - guiParameters.circleWidth),inradius13, 32);
+		ringMesh13.geometry = ringGeometry13; 
+		ringGeometry14.dispose();
+		ringGeometry14 = new THREE.RingGeometry((inradius14 - guiParameters.circleWidth),inradius14, 32);
+		ringMesh14.geometry = ringGeometry14; 
+		ringGeometry15.dispose();
+		ringGeometry15 = new THREE.RingGeometry((inradius15 - guiParameters.circleWidth),inradius15, 32);
+		ringMesh15.geometry = ringGeometry15; 
+		ringGeometry16.dispose();
+		ringGeometry16 = new THREE.RingGeometry((inradius16 - guiParameters.circleWidth),inradius16, 32);
+		ringMesh16.geometry = ringGeometry16; 
+		ringGeometry17.dispose();
+		ringGeometry17 = new THREE.RingGeometry((inradius17 - guiParameters.circleWidth),inradius17, 32);
+		ringMesh17.geometry = ringGeometry17; 
+		ringGeometry18.dispose();
+		ringGeometry18 = new THREE.RingGeometry((inradius18 - guiParameters.circleWidth),inradius18, 32);
+		ringMesh18.geometry = ringGeometry18; 
+		ringGeometry19.dispose();
+		ringGeometry19 = new THREE.RingGeometry((inradius19 - guiParameters.circleWidth),inradius19, 32);
+		ringMesh19.geometry = ringGeometry19; 
+		ringGeometry20.dispose();
+		ringGeometry20 = new THREE.RingGeometry((inradius20 - guiParameters.circleWidth),inradius20, 32);
+		ringMesh20.geometry = ringGeometry20; 
+	}
+
+	updateCircleWidth();
+
+	// generate the normals trough the incenter orthogonal to the face 
+	// getNormalsVectors generates the coordinates for the current values of the parameterized surface 
+	function getNormalsVectors(){
+		var vector1;
+		var vector2;
+
+		var normals = [];
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.425325404)-(0.951056516);
+		vector1[1] = (0.8506508085)-(0.);
+		vector1[2] = (0.)-(0.);
+
+		vector2[0] = (0.425325404)-(0.951056516);
+		vector2[1] = (0.262865556)-(0.);
+		vector2[2] = (0.809016994)-(0.);
+
+		var incenter = calulateIncenter([0.95105651599999996,0.,0.],[ 0.42532540400000002,0.85065080849999997,0.],[0.42532540400000002,0.262865556,0.80901699400000004]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.425325404)-(0.951056516);
+		vector1[1] = (0.8506508085)-(0.);
+		vector1[2] = (0.)-(0.);
+
+		vector2[0] = (-0.0449027976)-(0.951056516);
+		vector2[1] = (-0.0277514551)-(0.);
+		vector2[2] = (0.08541019649999999)-(0.);
+
+		var incenter = calulateIncenter([0.95105651599999996,0.,0.],[ 0.42532540400000002,0.85065080849999997,0.],[-0.044902797600000002,-0.027751455099999999,0.085410196499999994]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (-0.0449027976)-(0.951056516);
+		vector1[1] = (-0.0277514551)-(0.);
+		vector1[2] = (0.08541019649999999)-(0.);
+
+		vector2[0] = (0.425325404)-(0.951056516);
+		vector2[1] = (-0.6881909604000001)-(0.);
+		vector2[2] = (-0.4999999998)-(0.);
+
+		var incenter = calulateIncenter([0.95105651599999996,0.,0.],[ -0.044902797600000002,-0.027751455099999999,0.085410196499999994],[0.42532540400000002,-0.68819096040000005,-0.49999999979999998]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.425325404)-(0.951056516);
+		vector1[1] = (-0.6881909604000001)-(0.);
+		vector1[2] = (-0.4999999998)-(0.);
+
+		vector2[0] = (0.425325404)-(0.951056516);
+		vector2[1] = (-0.6881909604000001)-(0.);
+		vector2[2] = (0.4999999998)-(0.);
+
+		var incenter = calulateIncenter([0.95105651599999996,0.,0.],[ 0.42532540400000002,-0.68819096040000005,-0.49999999979999998],[0.42532540400000002,-0.68819096040000005,0.49999999979999998]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.425325404)-(0.951056516);
+		vector1[1] = (0.262865556)-(0.);
+		vector1[2] = (0.809016994)-(0.);
+
+		vector2[0] = (0.425325404)-(0.951056516);
+		vector2[1] = (-0.6881909604000001)-(0.);
+		vector2[2] = (0.4999999998)-(0.);
+
+		var incenter = calulateIncenter([0.95105651599999996,0.,0.],[ 0.42532540400000002,0.262865556,0.80901699400000004],[0.42532540400000002,-0.68819096040000005,0.49999999979999998]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.425325404)-(0.425325404);
+		vector1[1] = (0.262865556)-(0.8506508085);
+		vector1[2] = (0.809016994)-(0.);
+
+		vector2[0] = (-0.425325404)-(0.425325404);
+		vector2[1] = (0.6881909604000001)-(0.8506508085);
+		vector2[2] = (0.4999999998)-(0.);
+
+		var incenter = calulateIncenter([0.42532540400000002,0.85065080849999997,0.],[ 0.42532540400000002,0.262865556,0.80901699400000004],[-0.42532540400000002,0.68819096040000005,0.49999999979999998]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (-0.0449027976)-(0.425325404);
+		vector1[1] = (-0.0277514551)-(0.8506508085);
+		vector1[2] = (0.08541019649999999)-(0.);
+
+		vector2[0] = (-0.425325404)-(0.425325404);
+		vector2[1] = (0.6881909604000001)-(0.8506508085);
+		vector2[2] = (-0.4999999998)-(0.);
+
+		var incenter = calulateIncenter([0.42532540400000002,0.85065080849999997,0.],[ -0.044902797600000002,-0.027751455099999999,0.085410196499999994],[-0.42532540400000002,0.68819096040000005,-0.49999999979999998]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.425325404)-(-0.0449027976);
+		vector1[1] = (-0.6881909604000001)-(-0.0277514551);
+		vector1[2] = (-0.4999999998)-(0.08541019649999999);
+
+		vector2[0] = (-0.425325404)-(-0.0449027976);
+		vector2[1] = (-0.262865556)-(-0.0277514551);
+		vector2[2] = (-0.809016994)-(0.08541019649999999);
+
+		var incenter = calulateIncenter([-0.044902797600000002,-0.027751455099999999,0.085410196499999994],[ 0.42532540400000002,-0.68819096040000005,-0.49999999979999998],[-0.42532540400000002,-0.262865556,-0.80901699400000004]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.425325404)-(0.425325404);
+		vector1[1] = (-0.6881909604000001)-(-0.6881909604000001);
+		vector1[2] = (0.4999999998)-(-0.4999999998);
+
+		vector2[0] = (-0.425325404)-(0.425325404);
+		vector2[1] = (-0.8506508085)-(-0.6881909604000001);
+		vector2[2] = (0.)-(-0.4999999998);
+
+		var incenter = calulateIncenter([0.42532540400000002,-0.68819096040000005,-0.49999999979999998],[ 0.42532540400000002,-0.68819096040000005,0.49999999979999998],[-0.42532540400000002,-0.85065080849999997,0.]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.425325404)-(0.425325404);
+		vector1[1] = (-0.6881909604000001)-(0.262865556);
+		vector1[2] = (0.4999999998)-(0.809016994);
+
+		vector2[0] = (0.0449027976)-(0.425325404);
+		vector2[1] = (0.0277514551)-(0.262865556);
+		vector2[2] = (-0.08541019649999999)-(0.809016994);
+
+		var incenter = calulateIncenter([0.42532540400000002,0.262865556,0.80901699400000004],[ 0.42532540400000002,-0.68819096040000005,0.49999999979999998],[0.044902797600000002,0.027751455099999999,-0.085410196499999994]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (-0.425325404)-(0.425325404);
+		vector1[1] = (0.6881909604000001)-(0.8506508085);
+		vector1[2] = (0.4999999998)-(0.);
+
+		vector2[0] = (-0.425325404)-(0.425325404);
+		vector2[1] = (0.6881909604000001)-(0.8506508085);
+		vector2[2] = (-0.4999999998)-(0.);
+
+		var incenter = calulateIncenter([0.42532540400000002,0.85065080849999997,0.],[ -0.42532540400000002,0.68819096040000005,0.49999999979999998],[-0.42532540400000002,0.68819096040000005,-0.49999999979999998]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (-0.425325404)-(-0.0449027976);
+		vector1[1] = (0.6881909604000001)-(-0.0277514551);
+		vector1[2] = (-0.4999999998)-(0.08541019649999999);
+
+		vector2[0] = (-0.425325404)-(-0.0449027976);
+		vector2[1] = (-0.262865556)-(-0.0277514551);
+		vector2[2] = (-0.809016994)-(0.08541019649999999);
+
+		var incenter = calulateIncenter([-0.044902797600000002,-0.027751455099999999,0.085410196499999994],[ -0.42532540400000002,0.68819096040000005,-0.49999999979999998],[-0.42532540400000002,-0.262865556,-0.80901699400000004]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (-0.425325404)-(0.425325404);
+		vector1[1] = (-0.262865556)-(-0.6881909604000001);
+		vector1[2] = (-0.809016994)-(-0.4999999998);
+
+		vector2[0] = (-0.425325404)-(0.425325404);
+		vector2[1] = (-0.8506508085)-(-0.6881909604000001);
+		vector2[2] = (0.)-(-0.4999999998);
+
+		var incenter = calulateIncenter([0.42532540400000002,-0.68819096040000005,-0.49999999979999998],[ -0.42532540400000002,-0.262865556,-0.80901699400000004],[-0.42532540400000002,-0.85065080849999997,0.]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (-0.425325404)-(0.425325404);
+		vector1[1] = (-0.8506508085)-(-0.6881909604000001);
+		vector1[2] = (0.)-(0.4999999998);
+
+		vector2[0] = (0.0449027976)-(0.425325404);
+		vector2[1] = (0.0277514551)-(-0.6881909604000001);
+		vector2[2] = (-0.08541019649999999)-(0.4999999998);
+
+		var incenter = calulateIncenter([0.42532540400000002,-0.68819096040000005,0.49999999979999998],[ -0.42532540400000002,-0.85065080849999997,0.],[0.044902797600000002,0.027751455099999999,-0.085410196499999994]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (-0.425325404)-(0.425325404);
+		vector1[1] = (0.6881909604000001)-(0.262865556);
+		vector1[2] = (0.4999999998)-(0.809016994);
+
+		vector2[0] = (0.0449027976)-(0.425325404);
+		vector2[1] = (0.0277514551)-(0.262865556);
+		vector2[2] = (-0.08541019649999999)-(0.809016994);
+
+		var incenter = calulateIncenter([0.42532540400000002,0.262865556,0.80901699400000004],[ -0.42532540400000002,0.68819096040000005,0.49999999979999998],[0.044902797600000002,0.027751455099999999,-0.085410196499999994]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (-0.425325404)-(-0.425325404);
+		vector1[1] = (0.6881909604000001)-(0.6881909604000001);
+		vector1[2] = (-0.4999999998)-(0.4999999998);
+
+		vector2[0] = (-0.951056516)-(-0.425325404);
+		vector2[1] = (0.)-(0.6881909604000001);
+		vector2[2] = (0.)-(0.4999999998);
+
+		var incenter = calulateIncenter([-0.42532540400000002,0.68819096040000005,0.49999999979999998],[ -0.42532540400000002,0.68819096040000005,-0.49999999979999998],[-0.95105651599999996,0.,0.]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (-0.425325404)-(-0.425325404);
+		vector1[1] = (-0.262865556)-(0.6881909604000001);
+		vector1[2] = (-0.809016994)-(-0.4999999998);
+
+		vector2[0] = (-0.951056516)-(-0.425325404);
+		vector2[1] = (0.)-(0.6881909604000001);
+		vector2[2] = (0.)-(-0.4999999998);
+
+		var incenter = calulateIncenter([-0.42532540400000002,0.68819096040000005,-0.49999999979999998],[ -0.42532540400000002,-0.262865556,-0.80901699400000004],[-0.95105651599999996,0.,0.]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (-0.425325404)-(-0.425325404);
+		vector1[1] = (-0.8506508085)-(-0.262865556);
+		vector1[2] = (0.)-(-0.809016994);
+
+		vector2[0] = (-0.951056516)-(-0.425325404);
+		vector2[1] = (0.)-(-0.262865556);
+		vector2[2] = (0.)-(-0.809016994);
+
+		var incenter = calulateIncenter([-0.42532540400000002,-0.262865556,-0.80901699400000004],[ -0.42532540400000002,-0.85065080849999997,0.],[-0.95105651599999996,0.,0.]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.0449027976)-(-0.425325404);
+		vector1[1] = (0.0277514551)-(-0.8506508085);
+		vector1[2] = (-0.08541019649999999)-(0.);
+
+		vector2[0] = (-0.951056516)-(-0.425325404);
+		vector2[1] = (0.)-(-0.8506508085);
+		vector2[2] = (0.)-(0.);
+
+		var incenter = calulateIncenter([-0.42532540400000002,-0.85065080849999997,0.],[ 0.044902797600000002,0.027751455099999999,-0.085410196499999994],[-0.95105651599999996,0.,0.]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.0449027976)-(-0.425325404);
+		vector1[1] = (0.0277514551)-(0.6881909604000001);
+		vector1[2] = (-0.08541019649999999)-(0.4999999998);
+
+		vector2[0] = (-0.951056516)-(-0.425325404);
+		vector2[1] = (0.)-(0.6881909604000001);
+		vector2[2] = (0.)-(0.4999999998);
+
+		var incenter = calulateIncenter([-0.42532540400000002,0.68819096040000005,0.49999999979999998],[ 0.044902797600000002,0.027751455099999999,-0.085410196499999994],[-0.95105651599999996,0.,0.]);
+		normals.push([vector1, vector2, incenter]);
+
+	return normals;
+	}
+	// getNormalsCoordinates calculates the right coordinates for the ortogonality and fitting values from the gui 
+	function getNormalsCoordinates(){
+		var res = [];
+		var normals = getNormalsVectors(); 
+        for(var i = 0; i < normals.length; i++){
+            var plus = [];
+            var minus = [];
+
+            minus[0] = normals[i][2][0] - (1/2)*guiParameters.normalsLength*(normals[i][0][1]*normals[i][1][2] - normals[i][0][2]*normals[i][1][1]);
+            minus[1] = normals[i][2][1] - (1/2)*guiParameters.normalsLength*(normals[i][0][2]*normals[i][1][0] - normals[i][0][0]*normals[i][1][2]);
+            minus[2] = normals[i][2][2] - (1/2)*guiParameters.normalsLength*(normals[i][0][0]*normals[i][1][1] - normals[i][0][1]*normals[i][1][0]);
+
+            plus[0] = normals[i][2][0] + (1/2)*guiParameters.normalsLength*(normals[i][0][1]*normals[i][1][2] - normals[i][0][2]*normals[i][1][1]);
+            plus[1] = normals[i][2][1] + (1/2)*guiParameters.normalsLength*(normals[i][0][2]*normals[i][1][0] - normals[i][0][0]*normals[i][1][2]);
+            plus[2] = normals[i][2][2] + (1/2)*guiParameters.normalsLength*(normals[i][0][0]*normals[i][1][1] - normals[i][0][1]*normals[i][1][0]);
+
+            res.push(minus[0]);
+            res.push(minus[1]);
+            res.push(minus[2]);
+            res.push(plus[0]);
+            res.push(plus[1]);
+            res.push(plus[2]);
+        }
+        res = Float32Array.from(res);
+
+    
+		return res;
+	}
+
+
+    const normalsMaterial = new THREE.LineBasicMaterial( {
+        color: 0x000000,
+    } );
+    
+    const normalsGeometry = new THREE.BufferGeometry();
+    normalsGeometry.setAttribute( 'position', new THREE.BufferAttribute( getNormalsCoordinates(), 3 ) );
+    var normalsLine = new THREE.LineSegments( normalsGeometry, normalsMaterial );
+
+    function updateNormals(){
+        normalsGeometry.setAttribute( 'position', new THREE.BufferAttribute( getNormalsCoordinates(), 3 ) );
+        normalsLine = new THREE.LineSegments( normalsGeometry, normalsMaterial );
+    }
+    
+    normalsRoot.add(normalsLine);
+
+    
+	// generate automatic ranges for the intersections if the surface is not parameterized 
+	guiParameters.maxX = 0.951056516;
+	guiParameters.maxY = 0.8506508085;
+	guiParameters.maxZ = 0.809016994;
+	guiParameters.minX = -0.951056516;
+	guiParameters.minY = -0.8506508085;
+	guiParameters.minZ = -0.809016994;
+
+	guiParameters.planeX = 0.;
+	guiParameters.planeY = 0.;
+	guiParameters.planeZ = 0.;
+	// --- end of generated output --- //
+
+    const planeFolder = gui.addFolder("Intersection Planes");
+    planeFolder.add(guiParameters, 'planeXactive');
+    planeFolder.add(guiParameters, 'planeX', guiParameters.minX*1.1, guiParameters.maxX*1.1);
+    planeFolder.add(guiParameters, 'planeYactive');
+    planeFolder.add(guiParameters, 'planeY', guiParameters.minY*1.1, guiParameters.maxY*1.1);
+    planeFolder.add(guiParameters, 'planeZactive');
+    planeFolder.add(guiParameters, 'planeZ', guiParameters.minZ*1.1, guiParameters.maxZ*1.1);
+    
+    camera.position.z = Math.max((1.5)*guiParameters.minZ, 1)
+    camera.lookAt(0,0,-1);
+
+    scene.background = new THREE.Color( 'white' );
+
+    // add both roots to the scene
+    scene.add( meshRoot );
+    scene.add( wireRoot );
+    scene.add( vertexRoot );
+    scene.add( vertexlabelRoot );
+    scene.add( edgeRoot );
+    scene.add( ringRoot );
+    scene.add( normalsRoot );
+    scene.add( normalMeshRoot );
+
+    //presave some current gui parameters to only update if they change
+    var currentCircleWidth = guiParameters.circleWidth;
+
+    function animate() {
+        requestAnimationFrame( animate );
+        meshRoot.rotation.x += guiParameters.speedX/100;
+        meshRoot.rotation.y += guiParameters.speedY/100;
+        meshRoot.rotation.z += guiParameters.speedZ/100;
+
+        wireRoot.rotation.x += guiParameters.speedX/100;
+        wireRoot.rotation.y += guiParameters.speedY/100;
+        wireRoot.rotation.z += guiParameters.speedZ/100;
+
+        vertexRoot.rotation.x += guiParameters.speedX/100;
+        vertexRoot.rotation.y += guiParameters.speedY/100;
+        vertexRoot.rotation.z += guiParameters.speedZ/100;
+
+        vertexlabelRoot.rotation.x += guiParameters.speedX/100;
+        vertexlabelRoot.rotation.y += guiParameters.speedY/100;
+        vertexlabelRoot.rotation.z += guiParameters.speedZ/100;
+
+        edgeRoot.rotation.x += guiParameters.speedX/100;
+        edgeRoot.rotation.y += guiParameters.speedY/100;
+        edgeRoot.rotation.z += guiParameters.speedZ/100;
+
+        ringRoot.rotation.x += guiParameters.speedX/100;
+        ringRoot.rotation.y += guiParameters.speedY/100;
+        ringRoot.rotation.z += guiParameters.speedZ/100;
+
+        normalsRoot.rotation.x += guiParameters.speedX/100;
+        normalsRoot.rotation.y += guiParameters.speedY/100;
+        normalsRoot.rotation.z += guiParameters.speedZ/100;
+
+        normalMeshRoot.rotation.x += guiParameters.speedX/100;
+        normalMeshRoot.rotation.y += guiParameters.speedY/100;
+        normalMeshRoot.rotation.z += guiParameters.speedZ/100;
+
+        //update the light when the camera moves (with orbitcontrols)
+        light.position.set(camera.position.x, camera.position.y, camera.position.z);
+
+        planeX.constant = guiParameters.planeX;
+        planeY.constant = guiParameters.planeY;
+        planeZ.constant = guiParameters.planeZ;
+
+        activePlanes = [];
+        if(guiParameters.planeXactive){
+            activePlanes.push(planeX);
+        }
+        if(guiParameters.planeYactive){
+            activePlanes.push(planeY);
+        }
+        if(guiParameters.planeZactive){
+            activePlanes.push(planeZ);
+        }
+
+        if(vertexParametriziation){
+            updateFaceCoordinates();
+            if(guiParameters.edgeVisibility){
+                updateEdgeCoordinates();
+            }
+            if(guiParameters.vertexlabelVisibility || guiParameters.vertexVisibility){
+                updateVertexCoordinates();
+            }
+            if(guiParameters.circleVisibility){
+                updateCircles();
+            }
+        }                
+
+        //update stuff that changes from the gui
+        meshRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.opacity = guiParameters.transparency;
+                node.material.clippingPlanes = activePlanes;
+                if(guiParameters.normalsMaterial){
+                    node.material.opacity = 0;
+                }
+            }
+        } );
+
+        normalMeshRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.opacity = guiParameters.transparency;
+                node.material.clippingPlanes = activePlanes;
+                if(!guiParameters.normalsMaterial){
+                    node.material.opacity = 0;
+                }
+            }
+        } );
+
+        edgeRoot.traverse( function( node ) {
+            if ( node instanceof Line2 ) {
+                node.material.visible = guiParameters.edgeVisibility;
+                node.material.linewidth = guiParameters.edgeWidth/100;
+            }
+            if ( node instanceof THREE.LineSegments ) {
+                node.material.visible = guiParameters.edgeVisibility;
+            }
+        } );
+
+        vertexRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.visible = guiParameters.vertexVisibility;
+                node.scale.setScalar(guiParameters.vertexSize);
+            }
+        } );
+
+        vertexlabelRoot.traverse( function( node ) {
+            if( node instanceof CSS2DObject) {
+                node.visible = guiParameters.vertexlabelVisibility;
+            }
+        } );
+
+        ringRoot.traverse( function( node ) {
+            if( node instanceof THREE.Mesh) {
+                node.visible = guiParameters.circleVisibility;
+            }
+        } );
+
+        normalsRoot.traverse( function( node ) {
+            if( node instanceof THREE.LineSegments) {
+                node.visible = guiParameters.normalsVisibility;
+            }
+        } );
+
+        // update the circle width
+        if(guiParameters.circleVisibility && currentCircleWidth != guiParameters.circleWidth){
+            updateCircleWidth();
+            currentCircleWidth = guiParameters.circleWidth;
+        }
+
+        //update the normals length 
+        if(guiParameters.normalsVisibility){
+            updateNormals();
+        }
+
+        controls.update();
+
+        renderer.localClippingEnabled = true;
+
+        renderer.render( scene, camera );
+        labelRenderer.render( scene, camera );
+    }
+    animate();
+
+    //resize of window size changes
+    window.addEventListener( 'resize', onWindowResize );
+    function onWindowResize() {
+        camera.aspect = window.innerWidth / window.innerHeight;
+        camera.updateProjectionMatrix();
+
+        renderer.setSize( window.innerWidth, window.innerHeight );
+        labelRenderer.setSize( window.innerWidth, window.innerHeight );
+    }
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/htmls/ramified1.html b/htmls/ramified1.html
new file mode 100644
index 0000000000000000000000000000000000000000..8f6197e8536a97c2e8fff9f1efbcfb171129d36b
--- /dev/null
+++ b/htmls/ramified1.html
@@ -0,0 +1,919 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="utf-8">
+		<title>SimplicialSurface</title>
+		<style>
+			body { margin: 0; }
+		</style>
+
+
+	</head>
+	<body>
+
+<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>
+
+
+<script type="importmap">
+	{
+		"imports": {
+			"three": "https://unpkg.com/three@0.148.0/build/three.module.js",
+			"three/addons/": "https://unpkg.com/three@0.148.0/examples/jsm/",
+			"gui": "https://unpkg.com/dat.gui@0.7.9/build/dat.gui.module.js"
+		}
+	}
+</script>
+
+
+<script type="module">
+	import * as THREE from 'three';
+	import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
+	import { GUI } from 'gui';
+	import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
+	import { Line2 } from 'three/addons/lines/Line2.js';
+	import { LineMaterial } from 'three/addons/lines/LineMaterial.js';
+	import { LineGeometry } from 'three/addons/lines/LineGeometry.js';
+
+	//start scene and camera
+	const scene = new THREE.Scene();
+	const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 100 );
+
+	const renderer = new THREE.WebGLRenderer({ antialias: true });
+	renderer.setSize( window.innerWidth, window.innerHeight );
+	document.body.appendChild( renderer.domElement );
+
+	//Lights
+	const skyColor = 0xFFFFFF;
+	const skyIntensity = 0.3;
+	const skyLight = new THREE.AmbientLight(skyColor, skyIntensity);
+	scene.add(skyLight);
+
+	const color = 0xFFFFFF;
+	const intensity = 1;
+	const light = new THREE.PointLight(color, intensity);
+	light.position.set(0, 3, -5);
+	scene.add(light);
+
+	//create groups to add everything to
+	const meshRoot = new THREE.Group();
+	const wireRoot = new THREE.Group();
+	const vertexRoot = new THREE.Group();
+	const vertexlabelRoot = new THREE.Group();
+	const edgeRoot = new THREE.Group();
+	const ringRoot = new THREE.Group();
+	const normalsRoot = new THREE.Group();
+	const normalMeshRoot = new THREE.Group();
+
+	//parameters for the controls on the top right
+	var guiParameters = new function() { 
+		this.speedX = 0.0; 
+		this.speedY = 0.0; 
+		this.speedZ = 0.0;
+		this.transparency = 1;
+		this.edgeVisibility = false;
+		this.edgeWidth = 0.2;
+
+		this.vertexVisibility = true;
+		this.vertexlabelVisibility = false;
+		this.vertexSize = 1;
+		this.planeX = 0.0;
+		this.minX = -1.5;
+		this.maxX = 1.5;
+		this.planeXactive = false;
+		this.planeY = 0.0;
+		this.minY = -1.5;
+
+		this.maxY = 1.5;
+		this.planeYactive = false;
+		this.planeZ = 0.0;
+		this.minZ = -1.5;
+		this.maxZ = 1.5;
+		this.planeZactive = false;
+		this.normalsMaterial = false;
+		this.circleVisibility = false;
+		this.circleWidth = 0.005;
+		this.normalsVisibility = false;
+		this.normalsLength = 1;
+	} ;
+
+	//generate the plane for intersections
+	const planeX = new THREE.Plane( new THREE.Vector3( -1, 0, 0 ), guiParameters.planeX );
+	const planeY = new THREE.Plane( new THREE.Vector3( 0, -1, 0 ), guiParameters.planeY );
+	const planeZ = new THREE.Plane( new THREE.Vector3( 0, 0, -1 ), guiParameters.planeZ );
+
+	// the array which ones are currently active
+	var activePlanes = [];
+
+	//rederer for lables
+	const labelRenderer = new CSS2DRenderer();
+	labelRenderer.setSize( window.innerWidth, window.innerHeight );
+	labelRenderer.domElement.style.position = 'absolute';
+	labelRenderer.domElement.style.top = '0px';
+	document.body.appendChild( labelRenderer.domElement );
+	
+	//controls for mouse 
+	const controls = new OrbitControls( camera, labelRenderer.domElement );
+
+	//controls in the top right corner
+	var gui = new GUI();
+
+	const animationFolder = gui.addFolder("Animations");
+	animationFolder.add(guiParameters, 'speedX', 0, 5);
+	animationFolder.add(guiParameters, 'speedY', 0, 5);
+	animationFolder.add(guiParameters, 'speedZ', 0, 5);
+	animationFolder.open();
+
+	const controlFolder = gui.addFolder("Controls");
+	controlFolder.add(guiParameters, "transparency", 0, 1);
+	controlFolder.add(guiParameters, "edgeVisibility");
+	var edgeWidthGUI = controlFolder.add(guiParameters, "edgeWidth", 0.01, 2);
+	controlFolder.add(guiParameters, "vertexVisibility");
+	controlFolder.add(guiParameters, "vertexlabelVisibility");
+	controlFolder.add(guiParameters, "vertexSize", 0.1, 3);
+	controlFolder.add(guiParameters, "normalsMaterial");
+	controlFolder.add(guiParameters, "circleVisibility");
+	controlFolder.add(guiParameters, "circleWidth", 0.0001, 0.1);
+	controlFolder.add(guiParameters, "normalsVisibility");
+	controlFolder.add(guiParameters, "normalsLength", 0, 2);
+	controlFolder.open();
+
+	//generate a sphere geometry for the vertices
+	const sphereGeometry = new THREE.SphereGeometry( 0.02, 32, 16 );
+	sphereGeometry.transparent = guiParameters.vertexVisibility;
+	
+	//functions for later calculations
+
+	function calulateIncenter(A, B, C){
+		//we follow the math and variable names from here: https://math.stackexchange.com/questions/740111/incenter-of-triangle-in-3d
+		var a = Math.sqrt((B[0]-C[0])**2 + (B[1]-C[1])**2 + (B[2]-C[2])**2);
+		var b = Math.sqrt((C[0]-A[0])**2 + (C[1]-A[1])**2 + (C[2]-A[2])**2);
+		var c = Math.sqrt((A[0]-B[0])**2 + (A[1]-B[1])**2 + (A[2]-B[2])**2);
+
+		var res = [];
+		res[0] = a/(a+b+c)*A[0] + b/(a+b+c)*B[0] + c/(a+b+c)*C[0];
+		res[1] = a/(a+b+c)*A[1] + b/(a+b+c)*B[1] + c/(a+b+c)*C[1];
+		res[2] = a/(a+b+c)*A[2] + b/(a+b+c)*B[2] + c/(a+b+c)*C[2];
+
+		return res;
+	}
+
+	function calulateInradius(A, B, C){
+		var a = Math.sqrt((B[0]-C[0])**2 + (B[1]-C[1])**2 + (B[2]-C[2])**2);
+		var b = Math.sqrt((C[0]-A[0])**2 + (C[1]-A[1])**2 + (C[2]-A[2])**2);
+		var c = Math.sqrt((A[0]-B[0])**2 + (A[1]-B[1])**2 + (A[2]-B[2])**2);
+
+		var s = (a+b+c)/2;
+		var inradius = Math.sqrt(((s-a)*(s-b)*(s-c)) / s );
+
+		return inradius;
+	}
+
+	// --- start of generated output --- //
+
+	// preperations for parameterized vertex coordinates 
+	const vertexParametriziation = false;
+	// generate the faces color by color 
+	const geometry1 = new THREE.BufferGeometry();
+	function setVertices1(){
+		var vertices1 = new Float32Array( [
+				0.,-1.,0.,
+			0.,1.,0.,
+			0.5,1.,0.5,
+
+			0.,-1.,0.,
+			0.,1.,0.,
+			0.5,1.,-0.5,
+
+			0.,-1.,0.,
+			0.,1.,0.,
+			-0.5,1.,0.5,
+
+			0.,-1.,0.,
+			0.,1.,0.,
+			-0.5,1.,-0.5,
+
+					] ); 
+
+		return vertices1; 
+	}
+
+	geometry1.setAttribute( 'position', new THREE.BufferAttribute( setVertices1(), 3 ) );
+
+	// generate materials in the given color and normals material for the faces 
+
+    const materialNormal1 = new THREE.MeshNormalMaterial({
+        flatShading: true,
+    });
+    materialNormal1.transparent = true;
+    materialNormal1.side = THREE.DoubleSide;
+        
+    const material1 = new THREE.MeshPhongMaterial({
+        color: 0x049EF4,
+        flatShading: true,
+    });
+    material1.transparent = true;
+    material1.side = THREE.DoubleSide;
+        
+	// generate meshes for the faces from the materials with the vertex coordinates from before 
+
+    const mesh1 = new THREE.Mesh( geometry1, material1 );
+    mesh1.castShadow = true;                         
+    mesh1.receiveShadow = true;                      
+                                
+    meshRoot.add(mesh1);
+        
+    const meshNormal1 = new THREE.Mesh( geometry1, materialNormal1 );
+    mesh1.castShadow = true;                         
+    mesh1.receiveShadow = true;                      
+                                
+    normalMeshRoot.add(meshNormal1);
+        
+	// generate the edges grouped by color
+
+    const edgeMaterial1 = new LineMaterial( {
+        color: 0xFF0000,
+        linewidth: 3.,
+    } );
+        
+	function getEdges1(){
+		const edges1 = new Float32Array( [
+			0.,-1.,0.,
+			0.,1.,0.,
+
+		]);
+		return edges1;
+	}
+
+
+	// generate geometries and lines for the edges 
+
+    const edgeGeometry1 = new LineGeometry();
+    edgeGeometry1.setPositions(getEdges1() );
+
+    const edgeLine1 = new Line2( edgeGeometry1, edgeMaterial1 );
+    edgeRoot.add(edgeLine1);
+        
+	// update function to be called every frame 
+
+    const edgeMaterial2 = new LineMaterial( {
+        color: 0x000000,
+        linewidth: 3.,
+    } );
+        
+	function getEdges2(){
+		const edges2 = new Float32Array( [
+			0.,-1.,0.,
+			0.5,1.,0.5,
+
+			0.,-1.,0.,
+			0.5,1.,-0.5,
+
+			0.,-1.,0.,
+			-0.5,1.,0.5,
+
+			0.,-1.,0.,
+			-0.5,1.,-0.5,
+
+			0.,1.,0.,
+			0.5,1.,0.5,
+
+			0.,1.,0.,
+			0.5,1.,-0.5,
+
+			0.,1.,0.,
+			-0.5,1.,0.5,
+
+			0.,1.,0.,
+			-0.5,1.,-0.5,
+
+		]);
+		return edges2;
+	}
+
+
+	// generate geometries and lines for the edges 
+
+    const edgeGeometry2 = new LineGeometry();
+    edgeGeometry2.setPositions(getEdges2() );
+
+    const edgeLine2 = new Line2( edgeGeometry2, edgeMaterial2 );
+    edgeRoot.add(edgeLine2);
+        
+	// update function to be called every frame 
+	// generate labels and spheres for the vertices
+
+
+	function getVertex1(){
+		return [0.,-1.,0.,];
+	}
+	const sphereMaterial1 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere1 = new THREE.Mesh( sphereGeometry, sphereMaterial1 );
+	vertexRoot.add(sphere1);
+	sphere1.position.set(getVertex1()[0],getVertex1()[1],getVertex1()[2]);
+
+    const lableDiv1 = document.createElement( 'div' );
+    lableDiv1.className = 'label';
+    lableDiv1.textContent = '1';
+    lableDiv1.style.marginTop = '-1em';
+
+    const vertexLabel1 = new CSS2DObject( lableDiv1 );
+    vertexLabel1.position.set(getVertex1()[0],getVertex1()[1],getVertex1()[2]);
+    vertexlabelRoot.add( vertexLabel1 );
+            
+            
+
+	function getVertex2(){
+		return [0.,1.,0.,];
+	}
+	const sphereMaterial2 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere2 = new THREE.Mesh( sphereGeometry, sphereMaterial2 );
+	vertexRoot.add(sphere2);
+	sphere2.position.set(getVertex2()[0],getVertex2()[1],getVertex2()[2]);
+
+    const lableDiv2 = document.createElement( 'div' );
+    lableDiv2.className = 'label';
+    lableDiv2.textContent = '2';
+    lableDiv2.style.marginTop = '-1em';
+
+    const vertexLabel2 = new CSS2DObject( lableDiv2 );
+    vertexLabel2.position.set(getVertex2()[0],getVertex2()[1],getVertex2()[2]);
+    vertexlabelRoot.add( vertexLabel2 );
+            
+            
+
+	function getVertex3(){
+		return [0.5,1.,0.5,];
+	}
+	const sphereMaterial3 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere3 = new THREE.Mesh( sphereGeometry, sphereMaterial3 );
+	vertexRoot.add(sphere3);
+	sphere3.position.set(getVertex3()[0],getVertex3()[1],getVertex3()[2]);
+
+    const lableDiv3 = document.createElement( 'div' );
+    lableDiv3.className = 'label';
+    lableDiv3.textContent = '3';
+    lableDiv3.style.marginTop = '-1em';
+
+    const vertexLabel3 = new CSS2DObject( lableDiv3 );
+    vertexLabel3.position.set(getVertex3()[0],getVertex3()[1],getVertex3()[2]);
+    vertexlabelRoot.add( vertexLabel3 );
+            
+            
+
+	function getVertex4(){
+		return [0.5,1.,-0.5,];
+	}
+	const sphereMaterial4 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere4 = new THREE.Mesh( sphereGeometry, sphereMaterial4 );
+	vertexRoot.add(sphere4);
+	sphere4.position.set(getVertex4()[0],getVertex4()[1],getVertex4()[2]);
+
+    const lableDiv4 = document.createElement( 'div' );
+    lableDiv4.className = 'label';
+    lableDiv4.textContent = '4';
+    lableDiv4.style.marginTop = '-1em';
+
+    const vertexLabel4 = new CSS2DObject( lableDiv4 );
+    vertexLabel4.position.set(getVertex4()[0],getVertex4()[1],getVertex4()[2]);
+    vertexlabelRoot.add( vertexLabel4 );
+            
+            
+
+	function getVertex5(){
+		return [-0.5,1.,0.5,];
+	}
+	const sphereMaterial5 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere5 = new THREE.Mesh( sphereGeometry, sphereMaterial5 );
+	vertexRoot.add(sphere5);
+	sphere5.position.set(getVertex5()[0],getVertex5()[1],getVertex5()[2]);
+
+    const lableDiv5 = document.createElement( 'div' );
+    lableDiv5.className = 'label';
+    lableDiv5.textContent = '5';
+    lableDiv5.style.marginTop = '-1em';
+
+    const vertexLabel5 = new CSS2DObject( lableDiv5 );
+    vertexLabel5.position.set(getVertex5()[0],getVertex5()[1],getVertex5()[2]);
+    vertexlabelRoot.add( vertexLabel5 );
+            
+            
+
+	function getVertex6(){
+		return [-0.5,1.,-0.5,];
+	}
+	const sphereMaterial6 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere6 = new THREE.Mesh( sphereGeometry, sphereMaterial6 );
+	vertexRoot.add(sphere6);
+	sphere6.position.set(getVertex6()[0],getVertex6()[1],getVertex6()[2]);
+
+    const lableDiv6 = document.createElement( 'div' );
+    lableDiv6.className = 'label';
+    lableDiv6.textContent = '6';
+    lableDiv6.style.marginTop = '-1em';
+
+    const vertexLabel6 = new CSS2DObject( lableDiv6 );
+    vertexLabel6.position.set(getVertex6()[0],getVertex6()[1],getVertex6()[2]);
+    vertexlabelRoot.add( vertexLabel6 );
+            
+            	// generate the rings for the incircles 
+
+	var inradius1 = calulateInradius(getVertex1(), getVertex2(), getVertex3());
+	var incenter1 = calulateIncenter(getVertex1(), getVertex2(), getVertex3());
+	var ringGeometry1 = new THREE.RingGeometry((inradius1 - 0.005),inradius1, 32);
+	const ringMaterial1 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh1 = new THREE.Mesh(ringGeometry1, ringMaterial1);
+
+	function setCircleRotation1(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.,-1.,0.],[ 0.,1.,0.],[0.5,1.,0.5]);
+
+        ringMesh1.position.setX(incenter[0]);
+        ringMesh1.position.setY(incenter[1]);
+        ringMesh1.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex1(), getVertex2(), getVertex3());
+        var relRadius = inradius/inradius1;
+
+        ringMesh1.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A1 = new THREE.Vector3(0.,-1.,0.);
+        const B1 = new THREE.Vector3(0.,1.,0.);
+        const C1 = new THREE.Vector3(0.5,1.,0.5);
+
+        const normalVec1 = new THREE.Vector3();
+        normalVec1.crossVectors(B1.sub(A1), C1.sub(A1));
+        normalVec1.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal1 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation1 = new THREE.Quaternion();
+        quaternionRotation1.setFromUnitVectors(initialNormal1, normalVec1);
+
+        ringMesh1.setRotationFromQuaternion(quaternionRotation1);
+
+        return quaternionRotation1;
+    }
+
+    ringRoot.add(ringMesh1);
+            
+	var inradius2 = calulateInradius(getVertex1(), getVertex2(), getVertex4());
+	var incenter2 = calulateIncenter(getVertex1(), getVertex2(), getVertex4());
+	var ringGeometry2 = new THREE.RingGeometry((inradius2 - 0.005),inradius2, 32);
+	const ringMaterial2 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh2 = new THREE.Mesh(ringGeometry2, ringMaterial2);
+
+	function setCircleRotation2(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.,-1.,0.],[ 0.,1.,0.],[0.5,1.,-0.5]);
+
+        ringMesh2.position.setX(incenter[0]);
+        ringMesh2.position.setY(incenter[1]);
+        ringMesh2.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex1(), getVertex2(), getVertex4());
+        var relRadius = inradius/inradius2;
+
+        ringMesh2.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A2 = new THREE.Vector3(0.,-1.,0.);
+        const B2 = new THREE.Vector3(0.,1.,0.);
+        const C2 = new THREE.Vector3(0.5,1.,-0.5);
+
+        const normalVec2 = new THREE.Vector3();
+        normalVec2.crossVectors(B2.sub(A2), C2.sub(A2));
+        normalVec2.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal2 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation2 = new THREE.Quaternion();
+        quaternionRotation2.setFromUnitVectors(initialNormal2, normalVec2);
+
+        ringMesh2.setRotationFromQuaternion(quaternionRotation2);
+
+        return quaternionRotation2;
+    }
+
+    ringRoot.add(ringMesh2);
+            
+	var inradius3 = calulateInradius(getVertex1(), getVertex2(), getVertex5());
+	var incenter3 = calulateIncenter(getVertex1(), getVertex2(), getVertex5());
+	var ringGeometry3 = new THREE.RingGeometry((inradius3 - 0.005),inradius3, 32);
+	const ringMaterial3 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh3 = new THREE.Mesh(ringGeometry3, ringMaterial3);
+
+	function setCircleRotation3(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.,-1.,0.],[ 0.,1.,0.],[-0.5,1.,0.5]);
+
+        ringMesh3.position.setX(incenter[0]);
+        ringMesh3.position.setY(incenter[1]);
+        ringMesh3.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex1(), getVertex2(), getVertex5());
+        var relRadius = inradius/inradius3;
+
+        ringMesh3.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A3 = new THREE.Vector3(0.,-1.,0.);
+        const B3 = new THREE.Vector3(0.,1.,0.);
+        const C3 = new THREE.Vector3(-0.5,1.,0.5);
+
+        const normalVec3 = new THREE.Vector3();
+        normalVec3.crossVectors(B3.sub(A3), C3.sub(A3));
+        normalVec3.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal3 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation3 = new THREE.Quaternion();
+        quaternionRotation3.setFromUnitVectors(initialNormal3, normalVec3);
+
+        ringMesh3.setRotationFromQuaternion(quaternionRotation3);
+
+        return quaternionRotation3;
+    }
+
+    ringRoot.add(ringMesh3);
+            
+	var inradius4 = calulateInradius(getVertex1(), getVertex2(), getVertex6());
+	var incenter4 = calulateIncenter(getVertex1(), getVertex2(), getVertex6());
+	var ringGeometry4 = new THREE.RingGeometry((inradius4 - 0.005),inradius4, 32);
+	const ringMaterial4 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh4 = new THREE.Mesh(ringGeometry4, ringMaterial4);
+
+	function setCircleRotation4(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.,-1.,0.],[ 0.,1.,0.],[-0.5,1.,-0.5]);
+
+        ringMesh4.position.setX(incenter[0]);
+        ringMesh4.position.setY(incenter[1]);
+        ringMesh4.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex1(), getVertex2(), getVertex6());
+        var relRadius = inradius/inradius4;
+
+        ringMesh4.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A4 = new THREE.Vector3(0.,-1.,0.);
+        const B4 = new THREE.Vector3(0.,1.,0.);
+        const C4 = new THREE.Vector3(-0.5,1.,-0.5);
+
+        const normalVec4 = new THREE.Vector3();
+        normalVec4.crossVectors(B4.sub(A4), C4.sub(A4));
+        normalVec4.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal4 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation4 = new THREE.Quaternion();
+        quaternionRotation4.setFromUnitVectors(initialNormal4, normalVec4);
+
+        ringMesh4.setRotationFromQuaternion(quaternionRotation4);
+
+        return quaternionRotation4;
+    }
+
+    ringRoot.add(ringMesh4);
+            	// function to update the circles every frame 
+	function updateCircles(){
+		setCircleRotation1();
+		setCircleRotation2();
+		setCircleRotation3();
+		setCircleRotation4();
+	}
+
+	// needs to be called once to be initialized 
+	updateCircles();
+
+	// function to update the circles width, that is called every frame even if the surface is not parameterized 
+	function updateCircleWidth(){
+		ringGeometry1.dispose();
+		ringGeometry1 = new THREE.RingGeometry((inradius1 - guiParameters.circleWidth),inradius1, 32);
+		ringMesh1.geometry = ringGeometry1; 
+		ringGeometry2.dispose();
+		ringGeometry2 = new THREE.RingGeometry((inradius2 - guiParameters.circleWidth),inradius2, 32);
+		ringMesh2.geometry = ringGeometry2; 
+		ringGeometry3.dispose();
+		ringGeometry3 = new THREE.RingGeometry((inradius3 - guiParameters.circleWidth),inradius3, 32);
+		ringMesh3.geometry = ringGeometry3; 
+		ringGeometry4.dispose();
+		ringGeometry4 = new THREE.RingGeometry((inradius4 - guiParameters.circleWidth),inradius4, 32);
+		ringMesh4.geometry = ringGeometry4; 
+	}
+
+	updateCircleWidth();
+
+	// generate the normals trough the incenter orthogonal to the face 
+	// getNormalsVectors generates the coordinates for the current values of the parameterized surface 
+	function getNormalsVectors(){
+		var vector1;
+		var vector2;
+
+		var normals = [];
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.)-(0.);
+		vector1[1] = (1.)-(-1.);
+		vector1[2] = (0.)-(0.);
+
+		vector2[0] = (0.5)-(0.);
+		vector2[1] = (1.)-(-1.);
+		vector2[2] = (0.5)-(0.);
+
+		var incenter = calulateIncenter([0.,-1.,0.],[ 0.,1.,0.],[0.5,1.,0.5]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.)-(0.);
+		vector1[1] = (1.)-(-1.);
+		vector1[2] = (0.)-(0.);
+
+		vector2[0] = (0.5)-(0.);
+		vector2[1] = (1.)-(-1.);
+		vector2[2] = (-0.5)-(0.);
+
+		var incenter = calulateIncenter([0.,-1.,0.],[ 0.,1.,0.],[0.5,1.,-0.5]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.)-(0.);
+		vector1[1] = (1.)-(-1.);
+		vector1[2] = (0.)-(0.);
+
+		vector2[0] = (-0.5)-(0.);
+		vector2[1] = (1.)-(-1.);
+		vector2[2] = (0.5)-(0.);
+
+		var incenter = calulateIncenter([0.,-1.,0.],[ 0.,1.,0.],[-0.5,1.,0.5]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.)-(0.);
+		vector1[1] = (1.)-(-1.);
+		vector1[2] = (0.)-(0.);
+
+		vector2[0] = (-0.5)-(0.);
+		vector2[1] = (1.)-(-1.);
+		vector2[2] = (-0.5)-(0.);
+
+		var incenter = calulateIncenter([0.,-1.,0.],[ 0.,1.,0.],[-0.5,1.,-0.5]);
+		normals.push([vector1, vector2, incenter]);
+
+	return normals;
+	}
+	// getNormalsCoordinates calculates the right coordinates for the ortogonality and fitting values from the gui 
+	function getNormalsCoordinates(){
+		var res = [];
+		var normals = getNormalsVectors(); 
+        for(var i = 0; i < normals.length; i++){
+            var plus = [];
+            var minus = [];
+
+            minus[0] = normals[i][2][0] - (1/2)*guiParameters.normalsLength*(normals[i][0][1]*normals[i][1][2] - normals[i][0][2]*normals[i][1][1]);
+            minus[1] = normals[i][2][1] - (1/2)*guiParameters.normalsLength*(normals[i][0][2]*normals[i][1][0] - normals[i][0][0]*normals[i][1][2]);
+            minus[2] = normals[i][2][2] - (1/2)*guiParameters.normalsLength*(normals[i][0][0]*normals[i][1][1] - normals[i][0][1]*normals[i][1][0]);
+
+            plus[0] = normals[i][2][0] + (1/2)*guiParameters.normalsLength*(normals[i][0][1]*normals[i][1][2] - normals[i][0][2]*normals[i][1][1]);
+            plus[1] = normals[i][2][1] + (1/2)*guiParameters.normalsLength*(normals[i][0][2]*normals[i][1][0] - normals[i][0][0]*normals[i][1][2]);
+            plus[2] = normals[i][2][2] + (1/2)*guiParameters.normalsLength*(normals[i][0][0]*normals[i][1][1] - normals[i][0][1]*normals[i][1][0]);
+
+            res.push(minus[0]);
+            res.push(minus[1]);
+            res.push(minus[2]);
+            res.push(plus[0]);
+            res.push(plus[1]);
+            res.push(plus[2]);
+        }
+        res = Float32Array.from(res);
+
+    
+		return res;
+	}
+
+
+    const normalsMaterial = new THREE.LineBasicMaterial( {
+        color: 0x000000,
+    } );
+    
+    const normalsGeometry = new THREE.BufferGeometry();
+    normalsGeometry.setAttribute( 'position', new THREE.BufferAttribute( getNormalsCoordinates(), 3 ) );
+    var normalsLine = new THREE.LineSegments( normalsGeometry, normalsMaterial );
+
+    function updateNormals(){
+        normalsGeometry.setAttribute( 'position', new THREE.BufferAttribute( getNormalsCoordinates(), 3 ) );
+        normalsLine = new THREE.LineSegments( normalsGeometry, normalsMaterial );
+    }
+    
+    normalsRoot.add(normalsLine);
+
+    
+	// generate automatic ranges for the intersections if the surface is not parameterized 
+	guiParameters.maxX = 0.5;
+	guiParameters.maxY = 1.;
+	guiParameters.maxZ = 0.5;
+	guiParameters.minX = -0.5;
+	guiParameters.minY = -1.;
+	guiParameters.minZ = -0.5;
+
+	guiParameters.planeX = 0.;
+	guiParameters.planeY = 0.;
+	guiParameters.planeZ = 0.;
+	// --- end of generated output --- //
+
+    const planeFolder = gui.addFolder("Intersection Planes");
+    planeFolder.add(guiParameters, 'planeXactive');
+    planeFolder.add(guiParameters, 'planeX', guiParameters.minX*1.1, guiParameters.maxX*1.1);
+    planeFolder.add(guiParameters, 'planeYactive');
+    planeFolder.add(guiParameters, 'planeY', guiParameters.minY*1.1, guiParameters.maxY*1.1);
+    planeFolder.add(guiParameters, 'planeZactive');
+    planeFolder.add(guiParameters, 'planeZ', guiParameters.minZ*1.1, guiParameters.maxZ*1.1);
+    
+    camera.position.z = Math.max((1.5)*guiParameters.minZ, 1)
+    camera.lookAt(0,0,-1);
+
+    scene.background = new THREE.Color( 'white' );
+
+    // add both roots to the scene
+    scene.add( meshRoot );
+    scene.add( wireRoot );
+    scene.add( vertexRoot );
+    scene.add( vertexlabelRoot );
+    scene.add( edgeRoot );
+    scene.add( ringRoot );
+    scene.add( normalsRoot );
+    scene.add( normalMeshRoot );
+
+    //presave some current gui parameters to only update if they change
+    var currentCircleWidth = guiParameters.circleWidth;
+
+    function animate() {
+        requestAnimationFrame( animate );
+        meshRoot.rotation.x += guiParameters.speedX/100;
+        meshRoot.rotation.y += guiParameters.speedY/100;
+        meshRoot.rotation.z += guiParameters.speedZ/100;
+
+        wireRoot.rotation.x += guiParameters.speedX/100;
+        wireRoot.rotation.y += guiParameters.speedY/100;
+        wireRoot.rotation.z += guiParameters.speedZ/100;
+
+        vertexRoot.rotation.x += guiParameters.speedX/100;
+        vertexRoot.rotation.y += guiParameters.speedY/100;
+        vertexRoot.rotation.z += guiParameters.speedZ/100;
+
+        vertexlabelRoot.rotation.x += guiParameters.speedX/100;
+        vertexlabelRoot.rotation.y += guiParameters.speedY/100;
+        vertexlabelRoot.rotation.z += guiParameters.speedZ/100;
+
+        edgeRoot.rotation.x += guiParameters.speedX/100;
+        edgeRoot.rotation.y += guiParameters.speedY/100;
+        edgeRoot.rotation.z += guiParameters.speedZ/100;
+
+        ringRoot.rotation.x += guiParameters.speedX/100;
+        ringRoot.rotation.y += guiParameters.speedY/100;
+        ringRoot.rotation.z += guiParameters.speedZ/100;
+
+        normalsRoot.rotation.x += guiParameters.speedX/100;
+        normalsRoot.rotation.y += guiParameters.speedY/100;
+        normalsRoot.rotation.z += guiParameters.speedZ/100;
+
+        normalMeshRoot.rotation.x += guiParameters.speedX/100;
+        normalMeshRoot.rotation.y += guiParameters.speedY/100;
+        normalMeshRoot.rotation.z += guiParameters.speedZ/100;
+
+        //update the light when the camera moves (with orbitcontrols)
+        light.position.set(camera.position.x, camera.position.y, camera.position.z);
+
+        planeX.constant = guiParameters.planeX;
+        planeY.constant = guiParameters.planeY;
+        planeZ.constant = guiParameters.planeZ;
+
+        activePlanes = [];
+        if(guiParameters.planeXactive){
+            activePlanes.push(planeX);
+        }
+        if(guiParameters.planeYactive){
+            activePlanes.push(planeY);
+        }
+        if(guiParameters.planeZactive){
+            activePlanes.push(planeZ);
+        }
+
+        if(vertexParametriziation){
+            updateFaceCoordinates();
+            if(guiParameters.edgeVisibility){
+                updateEdgeCoordinates();
+            }
+            if(guiParameters.vertexlabelVisibility || guiParameters.vertexVisibility){
+                updateVertexCoordinates();
+            }
+            if(guiParameters.circleVisibility){
+                updateCircles();
+            }
+        }                
+
+        //update stuff that changes from the gui
+        meshRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.opacity = guiParameters.transparency;
+                node.material.clippingPlanes = activePlanes;
+                if(guiParameters.normalsMaterial){
+                    node.material.opacity = 0;
+                }
+            }
+        } );
+
+        normalMeshRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.opacity = guiParameters.transparency;
+                node.material.clippingPlanes = activePlanes;
+                if(!guiParameters.normalsMaterial){
+                    node.material.opacity = 0;
+                }
+            }
+        } );
+
+        edgeRoot.traverse( function( node ) {
+            if ( node instanceof Line2 ) {
+                node.material.visible = guiParameters.edgeVisibility;
+                node.material.linewidth = guiParameters.edgeWidth/100;
+            }
+            if ( node instanceof THREE.LineSegments ) {
+                node.material.visible = guiParameters.edgeVisibility;
+            }
+        } );
+
+        vertexRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.visible = guiParameters.vertexVisibility;
+                node.scale.setScalar(guiParameters.vertexSize);
+            }
+        } );
+
+        vertexlabelRoot.traverse( function( node ) {
+            if( node instanceof CSS2DObject) {
+                node.visible = guiParameters.vertexlabelVisibility;
+            }
+        } );
+
+        ringRoot.traverse( function( node ) {
+            if( node instanceof THREE.Mesh) {
+                node.visible = guiParameters.circleVisibility;
+            }
+        } );
+
+        normalsRoot.traverse( function( node ) {
+            if( node instanceof THREE.LineSegments) {
+                node.visible = guiParameters.normalsVisibility;
+            }
+        } );
+
+        // update the circle width
+        if(guiParameters.circleVisibility && currentCircleWidth != guiParameters.circleWidth){
+            updateCircleWidth();
+            currentCircleWidth = guiParameters.circleWidth;
+        }
+
+        //update the normals length 
+        if(guiParameters.normalsVisibility){
+            updateNormals();
+        }
+
+        controls.update();
+
+        renderer.localClippingEnabled = true;
+
+        renderer.render( scene, camera );
+        labelRenderer.render( scene, camera );
+    }
+    animate();
+
+    //resize of window size changes
+    window.addEventListener( 'resize', onWindowResize );
+    function onWindowResize() {
+        camera.aspect = window.innerWidth / window.innerHeight;
+        camera.updateProjectionMatrix();
+
+        renderer.setSize( window.innerWidth, window.innerHeight );
+        labelRenderer.setSize( window.innerWidth, window.innerHeight );
+    }
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test.stl b/test.stl
new file mode 100644
index 0000000000000000000000000000000000000000..8e9e1b52231e5eeef59798045057f02e1a6fced8
--- /dev/null
+++ b/test.stl
@@ -0,0 +1,16 @@
+solid test
+	facet normal -0.40824829046386307 0.40824829046386307 -0.81649658092772615 
+		outer loop
+			vertex 2. 0. 0. 
+			vertex 1. -1. 0. 
+			vertex -1. -1. 1. 
+		endloop
+	endfacet
+	facet normal -0.6616216370868464 0.74983785536509251 0. 
+		outer loop
+			vertex 2. 0. 0. 
+			vertex 0.29999999999999999 -1.5 0.5 
+			vertex 0.29999999999999999 -1.5 1. 
+		endloop
+	endfacet
+endsolid test
\ No newline at end of file
diff --git a/test_split2.stl b/test_split2.stl
new file mode 100644
index 0000000000000000000000000000000000000000..aadc3936c9ca3c149718350d76f0a38ee2a28fa6
--- /dev/null
+++ b/test_split2.stl
@@ -0,0 +1,58 @@
+solid test_split2
+	facet normal 0. 0. -1. 
+		outer loop
+			vertex 2. 0. 0. 
+			vertex 1. -1. 0. 
+			vertex 0.20000000000000001 -1.5 0. 
+		endloop
+	endfacet
+	facet normal 0. 0. 1. 
+		outer loop
+			vertex 2. 0. 0. 
+			vertex 0.20000000000000001 -1.5 0. 
+			vertex 0.5 -1.5 0. 
+		endloop
+	endfacet
+	facet normal -0.70534561585859823 0.70534561585859823 -0.070534561585859995 
+		outer loop
+			vertex 2. 0. 0. 
+			vertex 0.5 -1.5 0. 
+			vertex 0.40000000000000002 -1.5 1. 
+		endloop
+	endfacet
+	facet normal -0.1534291029830539 -0.42960148835255091 -0.88988879730171255 
+		outer loop
+			vertex 2. 0. 0. 
+			vertex 0.40000000000000002 -1.5 1. 
+			vertex -1. -1. 1. 
+		endloop
+	endfacet
+	facet normal -0.40824829046386307 0.40824829046386307 -0.81649658092772615 
+		outer loop
+			vertex 2. 0. 0. 
+			vertex 1. -1. 0. 
+			vertex -1. -1. 1. 
+		endloop
+	endfacet
+	facet normal -0.36369648372665397 0.58191437396264634 -0.72739296745330795 
+		outer loop
+			vertex 1. -1. 0. 
+			vertex 0.20000000000000001 -1.5 0. 
+			vertex -1. -1. 1. 
+		endloop
+	endfacet
+	facet normal -0.33557802760701216 -0.93961847729963399 0.06711560552140243 
+		outer loop
+			vertex 0.20000000000000001 -1.5 0. 
+			vertex 0.40000000000000002 -1.5 1. 
+			vertex -1. -1. 1. 
+		endloop
+	endfacet
+	facet normal 0. -1. 0. 
+		outer loop
+			vertex 0.20000000000000001 -1.5 0. 
+			vertex 0.5 -1.5 0. 
+			vertex 0.40000000000000002 -1.5 1. 
+		endloop
+	endfacet
+endsolid test_split2
\ No newline at end of file
diff --git a/un_ramified1.html b/un_ramified1.html
new file mode 100644
index 0000000000000000000000000000000000000000..d8ab75a07d42500403e0440e535162834ec58d78
--- /dev/null
+++ b/un_ramified1.html
@@ -0,0 +1,960 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="utf-8">
+		<title>SimplicialSurface</title>
+		<style>
+			body { margin: 0; }
+		</style>
+
+
+	</head>
+	<body>
+
+<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>
+
+
+<script type="importmap">
+	{
+		"imports": {
+			"three": "https://unpkg.com/three@0.148.0/build/three.module.js",
+			"three/addons/": "https://unpkg.com/three@0.148.0/examples/jsm/",
+			"gui": "https://unpkg.com/dat.gui@0.7.9/build/dat.gui.module.js"
+		}
+	}
+</script>
+
+
+<script type="module">
+	import * as THREE from 'three';
+	import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
+	import { GUI } from 'gui';
+	import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
+	import { Line2 } from 'three/addons/lines/Line2.js';
+	import { LineMaterial } from 'three/addons/lines/LineMaterial.js';
+	import { LineSegmentsGeometry } from 'three/addons/lines/LineSegmentsGeometry.js';
+
+	//start scene and camera
+	const scene = new THREE.Scene();
+	const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 100 );
+
+	const renderer = new THREE.WebGLRenderer({ antialias: true });
+	renderer.setSize( window.innerWidth, window.innerHeight );
+	document.body.appendChild( renderer.domElement );
+
+	//Lights
+	const skyColor = 0xFFFFFF;
+	const skyIntensity = 0.3;
+	const skyLight = new THREE.AmbientLight(skyColor, skyIntensity);
+	scene.add(skyLight);
+
+	const color = 0xFFFFFF;
+	const intensity = 1;
+	const light = new THREE.PointLight(color, intensity);
+	light.position.set(0, 3, -5);
+	scene.add(light);
+
+	//create groups to add everything to
+	const meshRoot = new THREE.Group();
+	const wireRoot = new THREE.Group();
+	const vertexRoot = new THREE.Group();
+	const vertexlabelRoot = new THREE.Group();
+	const edgeRoot = new THREE.Group();
+	const ringRoot = new THREE.Group();
+	const normalsRoot = new THREE.Group();
+	const normalMeshRoot = new THREE.Group();
+
+	//parameters for the controls on the top right
+	var guiParameters = new function() { 
+		this.speedX = 0.0; 
+		this.speedY = 0.0; 
+		this.speedZ = 0.0;
+		this.transparency = 1;
+		this.edgeVisibility = false;
+		this.edgeWidth = 0.2;
+
+		this.vertexVisibility = true;
+		this.vertexlabelVisibility = false;
+		this.vertexSize = 1;
+		this.planeX = 0.0;
+		this.minX = -1.5;
+		this.maxX = 1.5;
+		this.planeXactive = false;
+		this.planeY = 0.0;
+		this.minY = -1.5;
+
+		this.maxY = 1.5;
+		this.planeYactive = false;
+		this.planeZ = 0.0;
+		this.minZ = -1.5;
+		this.maxZ = 1.5;
+		this.planeZactive = false;
+		this.normalsMaterial = false;
+		this.circleVisibility = false;
+		this.circleWidth = 0.005;
+		this.normalsVisibility = false;
+		this.normalsLength = 1;
+	} ;
+
+	//generate the plane for intersections
+	const planeX = new THREE.Plane( new THREE.Vector3( -1, 0, 0 ), guiParameters.planeX );
+	const planeY = new THREE.Plane( new THREE.Vector3( 0, -1, 0 ), guiParameters.planeY );
+	const planeZ = new THREE.Plane( new THREE.Vector3( 0, 0, -1 ), guiParameters.planeZ );
+
+	// the array which ones are currently active
+	var activePlanes = [];
+
+	//rederer for lables
+	const labelRenderer = new CSS2DRenderer();
+	labelRenderer.setSize( window.innerWidth, window.innerHeight );
+	labelRenderer.domElement.style.position = 'absolute';
+	labelRenderer.domElement.style.top = '0px';
+	document.body.appendChild( labelRenderer.domElement );
+	
+	//controls for mouse 
+	const controls = new OrbitControls( camera, labelRenderer.domElement );
+
+	//controls in the top right corner
+	var gui = new GUI();
+
+	const animationFolder = gui.addFolder("Animations");
+	animationFolder.add(guiParameters, 'speedX', 0, 5);
+	animationFolder.add(guiParameters, 'speedY', 0, 5);
+	animationFolder.add(guiParameters, 'speedZ', 0, 5);
+	animationFolder.open();
+
+	const controlFolder = gui.addFolder("Controls");
+	controlFolder.add(guiParameters, "transparency", 0, 1);
+	controlFolder.add(guiParameters, "edgeVisibility");
+	var edgeWidthGUI = controlFolder.add(guiParameters, "edgeWidth", 0.01, 2);
+	controlFolder.add(guiParameters, "vertexVisibility");
+	controlFolder.add(guiParameters, "vertexlabelVisibility");
+	controlFolder.add(guiParameters, "vertexSize", 0.1, 3);
+	controlFolder.add(guiParameters, "normalsMaterial");
+	controlFolder.add(guiParameters, "circleVisibility");
+	controlFolder.add(guiParameters, "circleWidth", 0.0001, 0.1);
+	controlFolder.add(guiParameters, "normalsVisibility");
+	controlFolder.add(guiParameters, "normalsLength", 0, 2);
+	controlFolder.open();
+
+	//generate a sphere geometry for the vertices
+	const sphereGeometry = new THREE.SphereGeometry( 0.02, 32, 16 );
+	sphereGeometry.transparent = guiParameters.vertexVisibility;
+	
+	//functions for later calculations
+
+	function calulateIncenter(A, B, C){
+		//we follow the math and variable names from here: https://math.stackexchange.com/questions/740111/incenter-of-triangle-in-3d
+		var a = Math.sqrt((B[0]-C[0])**2 + (B[1]-C[1])**2 + (B[2]-C[2])**2);
+		var b = Math.sqrt((C[0]-A[0])**2 + (C[1]-A[1])**2 + (C[2]-A[2])**2);
+		var c = Math.sqrt((A[0]-B[0])**2 + (A[1]-B[1])**2 + (A[2]-B[2])**2);
+
+		var res = [];
+		res[0] = a/(a+b+c)*A[0] + b/(a+b+c)*B[0] + c/(a+b+c)*C[0];
+		res[1] = a/(a+b+c)*A[1] + b/(a+b+c)*B[1] + c/(a+b+c)*C[1];
+		res[2] = a/(a+b+c)*A[2] + b/(a+b+c)*B[2] + c/(a+b+c)*C[2];
+
+		return res;
+	}
+
+	function calulateInradius(A, B, C){
+		var a = Math.sqrt((B[0]-C[0])**2 + (B[1]-C[1])**2 + (B[2]-C[2])**2);
+		var b = Math.sqrt((C[0]-A[0])**2 + (C[1]-A[1])**2 + (C[2]-A[2])**2);
+		var c = Math.sqrt((A[0]-B[0])**2 + (A[1]-B[1])**2 + (A[2]-B[2])**2);
+
+		var s = (a+b+c)/2;
+		var inradius = Math.sqrt(((s-a)*(s-b)*(s-c)) / s );
+
+		return inradius;
+	}
+
+	// --- start of generated output --- //
+
+	// preperations for parameterized vertex coordinates 
+	const vertexParametriziation = false;
+	// generate the faces color by color 
+	const geometry1 = new THREE.BufferGeometry();
+	function setVertices1(){
+		var vertices1 = new Float32Array( [
+				0.,-1.,0.1,
+			0.,1.,0.1,
+			0.5,1.,0.5,
+
+			0.,-1.,-0.1,
+			0.,1.,-0.1,
+			0.5,1.,-0.5,
+
+			0.,-1.,0.1,
+			0.,1.,0.1,
+			-0.5,1.,0.5,
+
+			0.,-1.,-0.1,
+			0.,1.,-0.1,
+			-0.5,1.,-0.5,
+
+					] ); 
+
+		return vertices1; 
+	}
+
+	geometry1.setAttribute( 'position', new THREE.BufferAttribute( setVertices1(), 3 ) );
+
+	// generate materials in the given color and normals material for the faces 
+
+    const materialNormal1 = new THREE.MeshNormalMaterial({
+        flatShading: true,
+    });
+    materialNormal1.transparent = true;
+    materialNormal1.side = THREE.DoubleSide;
+        
+    const material1 = new THREE.MeshPhongMaterial({
+        color: 0x049EF4,
+        flatShading: true,
+    });
+    material1.transparent = true;
+    material1.side = THREE.DoubleSide;
+        
+	// generate meshes for the faces from the materials with the vertex coordinates from before 
+
+    const mesh1 = new THREE.Mesh( geometry1, material1 );
+    mesh1.castShadow = true;                         
+    mesh1.receiveShadow = true;                      
+                                
+    meshRoot.add(mesh1);
+        
+    const meshNormal1 = new THREE.Mesh( geometry1, materialNormal1 );
+    mesh1.castShadow = true;                         
+    mesh1.receiveShadow = true;                      
+                                
+    normalMeshRoot.add(meshNormal1);
+        
+	// generate the edges grouped by color
+
+    const edgeMaterial1 = new LineMaterial( {
+        color: 0xFF0000,
+        linewidth: 3.,
+    } );
+        
+	function getEdges1(){
+		const edges1 = new Float32Array( [
+			0.,-1.,-0.10000000000000001,
+			0.,1.,-0.10000000000000001,
+
+			0.,-1.,0.10000000000000001,
+			0.,1.,0.10000000000000001,
+
+		]);
+		return edges1;
+	}
+
+
+	// generate geometries and lines for the edges 
+
+    const edgeGeometry1 = new LineSegmentsGeometry();
+    edgeGeometry1.setPositions(getEdges1() );
+
+    const edgeLine1 = new Line2( edgeGeometry1, edgeMaterial1 );
+    edgeRoot.add(edgeLine1);
+        
+	// update function to be called every frame 
+
+    const edgeMaterial2 = new LineMaterial( {
+        color: 0x000000,
+        linewidth: 3.,
+    } );
+        
+	function getEdges2(){
+		const edges2 = new Float32Array( [
+			0.,-1.,-0.10000000000000001,
+			0.5,1.,-0.5,
+
+			0.,-1.,-0.10000000000000001,
+			-0.5,1.,-0.5,
+
+			0.,1.,-0.10000000000000001,
+			0.5,1.,-0.5,
+
+			0.,1.,-0.10000000000000001,
+			-0.5,1.,-0.5,
+
+			0.,-1.,0.10000000000000001,
+			0.5,1.,0.5,
+
+			0.,-1.,0.10000000000000001,
+			-0.5,1.,0.5,
+
+			0.,1.,0.10000000000000001,
+			0.5,1.,0.5,
+
+			0.,1.,0.10000000000000001,
+			-0.5,1.,0.5,
+
+		]);
+		return edges2;
+	}
+
+
+	// generate geometries and lines for the edges 
+
+    const edgeGeometry1 = new LineSegmentsGeometry();
+    edgeGeometry2.setPositions(getEdges2() );
+
+    const edgeLine2 = new Line2( edgeGeometry2, edgeMaterial2 );
+    edgeRoot.add(edgeLine2);
+        
+	// update function to be called every frame 
+	// generate labels and spheres for the vertices
+
+
+	function getVertex1(){
+		return [0.,-1.,-0.10000000000000001,];
+	}
+	const sphereMaterial1 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere1 = new THREE.Mesh( sphereGeometry, sphereMaterial1 );
+	vertexRoot.add(sphere1);
+	sphere1.position.set(getVertex1()[0],getVertex1()[1],getVertex1()[2]);
+
+    const lableDiv1 = document.createElement( 'div' );
+    lableDiv1.className = 'label';
+    lableDiv1.textContent = '1';
+    lableDiv1.style.marginTop = '-1em';
+
+    const vertexLabel1 = new CSS2DObject( lableDiv1 );
+    vertexLabel1.position.set(getVertex1()[0],getVertex1()[1],getVertex1()[2]);
+    vertexlabelRoot.add( vertexLabel1 );
+            
+            
+
+	function getVertex2(){
+		return [0.,1.,-0.10000000000000001,];
+	}
+	const sphereMaterial2 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere2 = new THREE.Mesh( sphereGeometry, sphereMaterial2 );
+	vertexRoot.add(sphere2);
+	sphere2.position.set(getVertex2()[0],getVertex2()[1],getVertex2()[2]);
+
+    const lableDiv2 = document.createElement( 'div' );
+    lableDiv2.className = 'label';
+    lableDiv2.textContent = '2';
+    lableDiv2.style.marginTop = '-1em';
+
+    const vertexLabel2 = new CSS2DObject( lableDiv2 );
+    vertexLabel2.position.set(getVertex2()[0],getVertex2()[1],getVertex2()[2]);
+    vertexlabelRoot.add( vertexLabel2 );
+            
+            
+
+	function getVertex3(){
+		return [0.,-1.,0.10000000000000001,];
+	}
+	const sphereMaterial3 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere3 = new THREE.Mesh( sphereGeometry, sphereMaterial3 );
+	vertexRoot.add(sphere3);
+	sphere3.position.set(getVertex3()[0],getVertex3()[1],getVertex3()[2]);
+
+    const lableDiv3 = document.createElement( 'div' );
+    lableDiv3.className = 'label';
+    lableDiv3.textContent = '3';
+    lableDiv3.style.marginTop = '-1em';
+
+    const vertexLabel3 = new CSS2DObject( lableDiv3 );
+    vertexLabel3.position.set(getVertex3()[0],getVertex3()[1],getVertex3()[2]);
+    vertexlabelRoot.add( vertexLabel3 );
+            
+            
+
+	function getVertex4(){
+		return [0.,1.,0.10000000000000001,];
+	}
+	const sphereMaterial4 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere4 = new THREE.Mesh( sphereGeometry, sphereMaterial4 );
+	vertexRoot.add(sphere4);
+	sphere4.position.set(getVertex4()[0],getVertex4()[1],getVertex4()[2]);
+
+    const lableDiv4 = document.createElement( 'div' );
+    lableDiv4.className = 'label';
+    lableDiv4.textContent = '4';
+    lableDiv4.style.marginTop = '-1em';
+
+    const vertexLabel4 = new CSS2DObject( lableDiv4 );
+    vertexLabel4.position.set(getVertex4()[0],getVertex4()[1],getVertex4()[2]);
+    vertexlabelRoot.add( vertexLabel4 );
+            
+            
+
+	function getVertex5(){
+		return [0.5,1.,0.5,];
+	}
+	const sphereMaterial5 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere5 = new THREE.Mesh( sphereGeometry, sphereMaterial5 );
+	vertexRoot.add(sphere5);
+	sphere5.position.set(getVertex5()[0],getVertex5()[1],getVertex5()[2]);
+
+    const lableDiv5 = document.createElement( 'div' );
+    lableDiv5.className = 'label';
+    lableDiv5.textContent = '5';
+    lableDiv5.style.marginTop = '-1em';
+
+    const vertexLabel5 = new CSS2DObject( lableDiv5 );
+    vertexLabel5.position.set(getVertex5()[0],getVertex5()[1],getVertex5()[2]);
+    vertexlabelRoot.add( vertexLabel5 );
+            
+            
+
+	function getVertex6(){
+		return [0.5,1.,-0.5,];
+	}
+	const sphereMaterial6 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere6 = new THREE.Mesh( sphereGeometry, sphereMaterial6 );
+	vertexRoot.add(sphere6);
+	sphere6.position.set(getVertex6()[0],getVertex6()[1],getVertex6()[2]);
+
+    const lableDiv6 = document.createElement( 'div' );
+    lableDiv6.className = 'label';
+    lableDiv6.textContent = '6';
+    lableDiv6.style.marginTop = '-1em';
+
+    const vertexLabel6 = new CSS2DObject( lableDiv6 );
+    vertexLabel6.position.set(getVertex6()[0],getVertex6()[1],getVertex6()[2]);
+    vertexlabelRoot.add( vertexLabel6 );
+            
+            
+
+	function getVertex7(){
+		return [-0.5,1.,0.5,];
+	}
+	const sphereMaterial7 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere7 = new THREE.Mesh( sphereGeometry, sphereMaterial7 );
+	vertexRoot.add(sphere7);
+	sphere7.position.set(getVertex7()[0],getVertex7()[1],getVertex7()[2]);
+
+    const lableDiv7 = document.createElement( 'div' );
+    lableDiv7.className = 'label';
+    lableDiv7.textContent = '7';
+    lableDiv7.style.marginTop = '-1em';
+
+    const vertexLabel7 = new CSS2DObject( lableDiv7 );
+    vertexLabel7.position.set(getVertex7()[0],getVertex7()[1],getVertex7()[2]);
+    vertexlabelRoot.add( vertexLabel7 );
+            
+            
+
+	function getVertex8(){
+		return [-0.5,1.,-0.5,];
+	}
+	const sphereMaterial8 = new THREE.MeshBasicMaterial( { color: 0xF58137 } );
+	const sphere8 = new THREE.Mesh( sphereGeometry, sphereMaterial8 );
+	vertexRoot.add(sphere8);
+	sphere8.position.set(getVertex8()[0],getVertex8()[1],getVertex8()[2]);
+
+    const lableDiv8 = document.createElement( 'div' );
+    lableDiv8.className = 'label';
+    lableDiv8.textContent = '8';
+    lableDiv8.style.marginTop = '-1em';
+
+    const vertexLabel8 = new CSS2DObject( lableDiv8 );
+    vertexLabel8.position.set(getVertex8()[0],getVertex8()[1],getVertex8()[2]);
+    vertexlabelRoot.add( vertexLabel8 );
+            
+            	// generate the rings for the incircles 
+
+	var inradius1 = calulateInradius(getVertex3(), getVertex4(), getVertex5());
+	var incenter1 = calulateIncenter(getVertex3(), getVertex4(), getVertex5());
+	var ringGeometry1 = new THREE.RingGeometry((inradius1 - 0.005),inradius1, 32);
+	const ringMaterial1 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh1 = new THREE.Mesh(ringGeometry1, ringMaterial1);
+
+	function setCircleRotation1(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.,-1.,0.10000000000000001],[ 0.,1.,0.10000000000000001],[0.5,1.,0.5]);
+
+        ringMesh1.position.setX(incenter[0]);
+        ringMesh1.position.setY(incenter[1]);
+        ringMesh1.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex3(), getVertex4(), getVertex5());
+        var relRadius = inradius/inradius1;
+
+        ringMesh1.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A1 = new THREE.Vector3(0.,-1.,0.10000000000000001);
+        const B1 = new THREE.Vector3(0.,1.,0.10000000000000001);
+        const C1 = new THREE.Vector3(0.5,1.,0.5);
+
+        const normalVec1 = new THREE.Vector3();
+        normalVec1.crossVectors(B1.sub(A1), C1.sub(A1));
+        normalVec1.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal1 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation1 = new THREE.Quaternion();
+        quaternionRotation1.setFromUnitVectors(initialNormal1, normalVec1);
+
+        ringMesh1.setRotationFromQuaternion(quaternionRotation1);
+
+        return quaternionRotation1;
+    }
+
+    ringRoot.add(ringMesh1);
+            
+	var inradius2 = calulateInradius(getVertex1(), getVertex2(), getVertex6());
+	var incenter2 = calulateIncenter(getVertex1(), getVertex2(), getVertex6());
+	var ringGeometry2 = new THREE.RingGeometry((inradius2 - 0.005),inradius2, 32);
+	const ringMaterial2 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh2 = new THREE.Mesh(ringGeometry2, ringMaterial2);
+
+	function setCircleRotation2(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.,-1.,-0.10000000000000001],[ 0.,1.,-0.10000000000000001],[0.5,1.,-0.5]);
+
+        ringMesh2.position.setX(incenter[0]);
+        ringMesh2.position.setY(incenter[1]);
+        ringMesh2.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex1(), getVertex2(), getVertex6());
+        var relRadius = inradius/inradius2;
+
+        ringMesh2.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A2 = new THREE.Vector3(0.,-1.,-0.10000000000000001);
+        const B2 = new THREE.Vector3(0.,1.,-0.10000000000000001);
+        const C2 = new THREE.Vector3(0.5,1.,-0.5);
+
+        const normalVec2 = new THREE.Vector3();
+        normalVec2.crossVectors(B2.sub(A2), C2.sub(A2));
+        normalVec2.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal2 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation2 = new THREE.Quaternion();
+        quaternionRotation2.setFromUnitVectors(initialNormal2, normalVec2);
+
+        ringMesh2.setRotationFromQuaternion(quaternionRotation2);
+
+        return quaternionRotation2;
+    }
+
+    ringRoot.add(ringMesh2);
+            
+	var inradius3 = calulateInradius(getVertex3(), getVertex4(), getVertex7());
+	var incenter3 = calulateIncenter(getVertex3(), getVertex4(), getVertex7());
+	var ringGeometry3 = new THREE.RingGeometry((inradius3 - 0.005),inradius3, 32);
+	const ringMaterial3 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh3 = new THREE.Mesh(ringGeometry3, ringMaterial3);
+
+	function setCircleRotation3(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.,-1.,0.10000000000000001],[ 0.,1.,0.10000000000000001],[-0.5,1.,0.5]);
+
+        ringMesh3.position.setX(incenter[0]);
+        ringMesh3.position.setY(incenter[1]);
+        ringMesh3.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex3(), getVertex4(), getVertex7());
+        var relRadius = inradius/inradius3;
+
+        ringMesh3.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A3 = new THREE.Vector3(0.,-1.,0.10000000000000001);
+        const B3 = new THREE.Vector3(0.,1.,0.10000000000000001);
+        const C3 = new THREE.Vector3(-0.5,1.,0.5);
+
+        const normalVec3 = new THREE.Vector3();
+        normalVec3.crossVectors(B3.sub(A3), C3.sub(A3));
+        normalVec3.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal3 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation3 = new THREE.Quaternion();
+        quaternionRotation3.setFromUnitVectors(initialNormal3, normalVec3);
+
+        ringMesh3.setRotationFromQuaternion(quaternionRotation3);
+
+        return quaternionRotation3;
+    }
+
+    ringRoot.add(ringMesh3);
+            
+	var inradius4 = calulateInradius(getVertex1(), getVertex2(), getVertex8());
+	var incenter4 = calulateIncenter(getVertex1(), getVertex2(), getVertex8());
+	var ringGeometry4 = new THREE.RingGeometry((inradius4 - 0.005),inradius4, 32);
+	const ringMaterial4 = new THREE.LineBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
+	const ringMesh4 = new THREE.Mesh(ringGeometry4, ringMaterial4);
+
+	function setCircleRotation4(){
+
+        //translate ring to incenter
+        var incenter = calulateIncenter([0.,-1.,-0.10000000000000001],[ 0.,1.,-0.10000000000000001],[-0.5,1.,-0.5]);
+
+        ringMesh4.position.setX(incenter[0]);
+        ringMesh4.position.setY(incenter[1]);
+        ringMesh4.position.setZ(incenter[2]);
+
+        // set the size right. Is done relative to the initial value, as we can only scale the mesh
+        var inradius = calulateInradius(getVertex1(), getVertex2(), getVertex8());
+        var relRadius = inradius/inradius4;
+
+        ringMesh4.scale.set(relRadius, relRadius, relRadius);
+
+        // rotate ring to right angle
+        const A4 = new THREE.Vector3(0.,-1.,-0.10000000000000001);
+        const B4 = new THREE.Vector3(0.,1.,-0.10000000000000001);
+        const C4 = new THREE.Vector3(-0.5,1.,-0.5);
+
+        const normalVec4 = new THREE.Vector3();
+        normalVec4.crossVectors(B4.sub(A4), C4.sub(A4));
+        normalVec4.normalize();
+
+        //initial normal vector of ringGeometry is (0,0,1), so we use that
+        const initialNormal4 = new THREE.Vector3(0,0,1);
+
+        const quaternionRotation4 = new THREE.Quaternion();
+        quaternionRotation4.setFromUnitVectors(initialNormal4, normalVec4);
+
+        ringMesh4.setRotationFromQuaternion(quaternionRotation4);
+
+        return quaternionRotation4;
+    }
+
+    ringRoot.add(ringMesh4);
+            	// function to update the circles every frame 
+	function updateCircles(){
+		setCircleRotation1();
+		setCircleRotation2();
+		setCircleRotation3();
+		setCircleRotation4();
+	}
+
+	// needs to be called once to be initialized 
+	updateCircles();
+
+	// function to update the circles width, that is called every frame even if the surface is not parameterized 
+	function updateCircleWidth(){
+		ringGeometry1.dispose();
+		ringGeometry1 = new THREE.RingGeometry((inradius1 - guiParameters.circleWidth),inradius1, 32);
+		ringMesh1.geometry = ringGeometry1; 
+		ringGeometry2.dispose();
+		ringGeometry2 = new THREE.RingGeometry((inradius2 - guiParameters.circleWidth),inradius2, 32);
+		ringMesh2.geometry = ringGeometry2; 
+		ringGeometry3.dispose();
+		ringGeometry3 = new THREE.RingGeometry((inradius3 - guiParameters.circleWidth),inradius3, 32);
+		ringMesh3.geometry = ringGeometry3; 
+		ringGeometry4.dispose();
+		ringGeometry4 = new THREE.RingGeometry((inradius4 - guiParameters.circleWidth),inradius4, 32);
+		ringMesh4.geometry = ringGeometry4; 
+	}
+
+	updateCircleWidth();
+
+	// generate the normals trough the incenter orthogonal to the face 
+	// getNormalsVectors generates the coordinates for the current values of the parameterized surface 
+	function getNormalsVectors(){
+		var vector1;
+		var vector2;
+
+		var normals = [];
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.)-(0.);
+		vector1[1] = (1.)-(-1.);
+		vector1[2] = (0.1)-(0.1);
+
+		vector2[0] = (0.5)-(0.);
+		vector2[1] = (1.)-(-1.);
+		vector2[2] = (0.5)-(0.1);
+
+		var incenter = calulateIncenter([0.,-1.,0.10000000000000001],[ 0.,1.,0.10000000000000001],[0.5,1.,0.5]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.)-(0.);
+		vector1[1] = (1.)-(-1.);
+		vector1[2] = (-0.1)-(-0.1);
+
+		vector2[0] = (0.5)-(0.);
+		vector2[1] = (1.)-(-1.);
+		vector2[2] = (-0.5)-(-0.1);
+
+		var incenter = calulateIncenter([0.,-1.,-0.10000000000000001],[ 0.,1.,-0.10000000000000001],[0.5,1.,-0.5]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.)-(0.);
+		vector1[1] = (1.)-(-1.);
+		vector1[2] = (0.1)-(0.1);
+
+		vector2[0] = (-0.5)-(0.);
+		vector2[1] = (1.)-(-1.);
+		vector2[2] = (0.5)-(0.1);
+
+		var incenter = calulateIncenter([0.,-1.,0.10000000000000001],[ 0.,1.,0.10000000000000001],[-0.5,1.,0.5]);
+		normals.push([vector1, vector2, incenter]);
+
+		vector1 = [];
+		vector2 = [];
+		vector1[0] = (0.)-(0.);
+		vector1[1] = (1.)-(-1.);
+		vector1[2] = (-0.1)-(-0.1);
+
+		vector2[0] = (-0.5)-(0.);
+		vector2[1] = (1.)-(-1.);
+		vector2[2] = (-0.5)-(-0.1);
+
+		var incenter = calulateIncenter([0.,-1.,-0.10000000000000001],[ 0.,1.,-0.10000000000000001],[-0.5,1.,-0.5]);
+		normals.push([vector1, vector2, incenter]);
+
+	return normals;
+	}
+	// getNormalsCoordinates calculates the right coordinates for the ortogonality and fitting values from the gui 
+	function getNormalsCoordinates(){
+		var res = [];
+		var normals = getNormalsVectors(); 
+        for(var i = 0; i < normals.length; i++){
+            var plus = [];
+            var minus = [];
+
+            minus[0] = normals[i][2][0] - (1/2)*guiParameters.normalsLength*(normals[i][0][1]*normals[i][1][2] - normals[i][0][2]*normals[i][1][1]);
+            minus[1] = normals[i][2][1] - (1/2)*guiParameters.normalsLength*(normals[i][0][2]*normals[i][1][0] - normals[i][0][0]*normals[i][1][2]);
+            minus[2] = normals[i][2][2] - (1/2)*guiParameters.normalsLength*(normals[i][0][0]*normals[i][1][1] - normals[i][0][1]*normals[i][1][0]);
+
+            plus[0] = normals[i][2][0] + (1/2)*guiParameters.normalsLength*(normals[i][0][1]*normals[i][1][2] - normals[i][0][2]*normals[i][1][1]);
+            plus[1] = normals[i][2][1] + (1/2)*guiParameters.normalsLength*(normals[i][0][2]*normals[i][1][0] - normals[i][0][0]*normals[i][1][2]);
+            plus[2] = normals[i][2][2] + (1/2)*guiParameters.normalsLength*(normals[i][0][0]*normals[i][1][1] - normals[i][0][1]*normals[i][1][0]);
+
+            res.push(minus[0]);
+            res.push(minus[1]);
+            res.push(minus[2]);
+            res.push(plus[0]);
+            res.push(plus[1]);
+            res.push(plus[2]);
+        }
+        res = Float32Array.from(res);
+
+    
+		return res;
+	}
+
+
+    const normalsMaterial = new THREE.LineBasicMaterial( {
+        color: 0x000000,
+    } );
+    
+    const normalsGeometry = new THREE.BufferGeometry();
+    normalsGeometry.setAttribute( 'position', new THREE.BufferAttribute( getNormalsCoordinates(), 3 ) );
+    var normalsLine = new THREE.LineSegments( normalsGeometry, normalsMaterial );
+
+    function updateNormals(){
+        normalsGeometry.setAttribute( 'position', new THREE.BufferAttribute( getNormalsCoordinates(), 3 ) );
+        normalsLine = new THREE.LineSegments( normalsGeometry, normalsMaterial );
+    }
+    
+    normalsRoot.add(normalsLine);
+
+    
+	// generate automatic ranges for the intersections if the surface is not parameterized 
+	guiParameters.maxX = 0.5;
+	guiParameters.maxY = 1.;
+	guiParameters.maxZ = 0.5;
+	guiParameters.minX = -0.5;
+	guiParameters.minY = -1.;
+	guiParameters.minZ = -0.5;
+
+	guiParameters.planeX = 0.;
+	guiParameters.planeY = 0.;
+	guiParameters.planeZ = 0.;
+	// --- end of generated output --- //
+
+    const planeFolder = gui.addFolder("Intersection Planes");
+    planeFolder.add(guiParameters, 'planeXactive');
+    planeFolder.add(guiParameters, 'planeX', guiParameters.minX*1.1, guiParameters.maxX*1.1);
+    planeFolder.add(guiParameters, 'planeYactive');
+    planeFolder.add(guiParameters, 'planeY', guiParameters.minY*1.1, guiParameters.maxY*1.1);
+    planeFolder.add(guiParameters, 'planeZactive');
+    planeFolder.add(guiParameters, 'planeZ', guiParameters.minZ*1.1, guiParameters.maxZ*1.1);
+    
+    camera.position.z = Math.min((1.5)*guiParameters.minZ, -1)
+    camera.lookAt(0,0,-1);
+
+    scene.background = new THREE.Color( 'white' );
+
+    // add both roots to the scene
+    scene.add( meshRoot );
+    scene.add( wireRoot );
+    scene.add( vertexRoot );
+    scene.add( vertexlabelRoot );
+    scene.add( edgeRoot );
+    scene.add( ringRoot );
+    scene.add( normalsRoot );
+    scene.add( normalMeshRoot );
+
+    //presave some current gui parameters to only update if they change
+    var currentCircleWidth = guiParameters.circleWidth;
+
+    function animate() {
+        requestAnimationFrame( animate );
+        meshRoot.rotation.x += guiParameters.speedX/100;
+        meshRoot.rotation.y += guiParameters.speedY/100;
+        meshRoot.rotation.z += guiParameters.speedZ/100;
+
+        wireRoot.rotation.x += guiParameters.speedX/100;
+        wireRoot.rotation.y += guiParameters.speedY/100;
+        wireRoot.rotation.z += guiParameters.speedZ/100;
+
+        vertexRoot.rotation.x += guiParameters.speedX/100;
+        vertexRoot.rotation.y += guiParameters.speedY/100;
+        vertexRoot.rotation.z += guiParameters.speedZ/100;
+
+        vertexlabelRoot.rotation.x += guiParameters.speedX/100;
+        vertexlabelRoot.rotation.y += guiParameters.speedY/100;
+        vertexlabelRoot.rotation.z += guiParameters.speedZ/100;
+
+        edgeRoot.rotation.x += guiParameters.speedX/100;
+        edgeRoot.rotation.y += guiParameters.speedY/100;
+        edgeRoot.rotation.z += guiParameters.speedZ/100;
+
+        ringRoot.rotation.x += guiParameters.speedX/100;
+        ringRoot.rotation.y += guiParameters.speedY/100;
+        ringRoot.rotation.z += guiParameters.speedZ/100;
+
+        normalsRoot.rotation.x += guiParameters.speedX/100;
+        normalsRoot.rotation.y += guiParameters.speedY/100;
+        normalsRoot.rotation.z += guiParameters.speedZ/100;
+
+        normalMeshRoot.rotation.x += guiParameters.speedX/100;
+        normalMeshRoot.rotation.y += guiParameters.speedY/100;
+        normalMeshRoot.rotation.z += guiParameters.speedZ/100;
+
+        //update the light when the camera moves (with orbitcontrols)
+        light.position.set(camera.position.x, camera.position.y, camera.position.z);
+
+        planeX.constant = guiParameters.planeX;
+        planeY.constant = guiParameters.planeY;
+        planeZ.constant = guiParameters.planeZ;
+
+        activePlanes = [];
+        if(guiParameters.planeXactive){
+            activePlanes.push(planeX);
+        }
+        if(guiParameters.planeYactive){
+            activePlanes.push(planeY);
+        }
+        if(guiParameters.planeZactive){
+            activePlanes.push(planeZ);
+        }
+
+        if(vertexParametriziation){
+            updateFaceCoordinates();
+            if(guiParameters.edgeVisibility){
+                updateEdgeCoordinates();
+            }
+            if(guiParameters.vertexlabelVisibility || guiParameters.vertexVisibility){
+                updateVertexCoordinates();
+            }
+            if(guiParameters.circleVisibility){
+                updateCircles();
+            }
+        }                
+
+        //update stuff that changes from the gui
+        meshRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.opacity = guiParameters.transparency;
+                node.material.clippingPlanes = activePlanes;
+                if(guiParameters.normalsMaterial){
+                    node.material.opacity = 0;
+                }
+            }
+        } );
+
+        normalMeshRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.opacity = guiParameters.transparency;
+                node.material.clippingPlanes = activePlanes;
+                if(!guiParameters.normalsMaterial){
+                    node.material.opacity = 0;
+                }
+            }
+        } );
+
+        edgeRoot.traverse( function( node ) {
+            if ( node instanceof Line2 ) {
+                node.material.visible = guiParameters.edgeVisibility;
+                node.material.linewidth = guiParameters.edgeWidth/100;
+            }
+            if ( node instanceof THREE.LineSegments ) {
+                node.material.visible = guiParameters.edgeVisibility;
+            }
+        } );
+
+        vertexRoot.traverse( function( node ) {
+            if ( node instanceof THREE.Mesh ) {
+                node.material.visible = guiParameters.vertexVisibility;
+                node.scale.setScalar(guiParameters.vertexSize);
+            }
+        } );
+
+        vertexlabelRoot.traverse( function( node ) {
+            if( node instanceof CSS2DObject) {
+                node.visible = guiParameters.vertexlabelVisibility;
+            }
+        } );
+
+        ringRoot.traverse( function( node ) {
+            if( node instanceof THREE.Mesh) {
+                node.visible = guiParameters.circleVisibility;
+            }
+        } );
+
+        normalsRoot.traverse( function( node ) {
+            if( node instanceof THREE.LineSegments) {
+                node.visible = guiParameters.normalsVisibility;
+            }
+        } );
+
+        // update the circle width
+        if(guiParameters.circleVisibility && currentCircleWidth != guiParameters.circleWidth){
+            updateCircleWidth();
+            currentCircleWidth = guiParameters.circleWidth;
+        }
+
+        //update the normals length 
+        if(guiParameters.normalsVisibility){
+            updateNormals();
+        }
+
+        controls.update();
+
+        renderer.localClippingEnabled = true;
+
+        renderer.render( scene, camera );
+        labelRenderer.render( scene, camera );
+    }
+    animate();
+
+    //resize of window size changes
+    window.addEventListener( 'resize', onWindowResize );
+    function onWindowResize() {
+        camera.aspect = window.innerWidth / window.innerHeight;
+        camera.updateProjectionMatrix();
+
+        renderer.setSize( window.innerWidth, window.innerHeight );
+        labelRenderer.setSize( window.innerWidth, window.innerHeight );
+    }
+</script>
+
+</body>
+</html>
\ No newline at end of file