diff --git a/src/heightmap.cpp b/src/heightmap.cpp
index 5e3b96fba70cc59e6cf6f27af0e6ea7e24e05eea..36c8b2d74e96595db4fa13db24a6992cc27484f0 100644
--- a/src/heightmap.cpp
+++ b/src/heightmap.cpp
@@ -58,6 +58,7 @@ Heightmap::Heightmap(std::string filename): _filename(filename) {
 		_minZ = min(_data, 2, 3);
 		_maxZ = max(_data, 2, 3);
 		_zRangeUm = (_maxZ - _minZ) / 10.; //in um
+		_zRangeUmOffset = 0.f;
 		std::cout << "Identified z range: " << _zRangeUm << " um (" << _minZ << " - " << _maxZ << ")" << std::endl;
 		/*Throw if _zRange is less than 1 A (i.e. it's probably 0)*/
 		if (_zRangeUm < 1e-4) {
@@ -76,6 +77,8 @@ Heightmap::Heightmap(std::string filename): _filename(filename) {
 		_minZ = min(_data, 2, 3); //should be 0
 		_maxZ = max(_data, 2, 3); //should be 1
 
+		std::cout << "Identified z range " << _minZ << " - " << _maxZ << std::endl;
+
 		/*Initialize Renderer Infrastructure*/
 		glGenBuffers(1, &_vbo);
 		glGenBuffers(1, &_ebo);
@@ -172,6 +175,8 @@ Heightmap::Heightmap(std::string filename): _filename(filename) {
 		std::string fragFile = std::string(SHADER_LOC) + std::string("heightmap0.frag");
 		_shader_ptr = ResourceManager::fetch_shader(vertFile, fragFile);
 		_scale = 0.5f;
+		_modelSpaceRot = glm::mat4(1.f);
+		_highlightingRadius = 0.05f;
 		_shader_ptr->use();
 		_shader_ptr->setFloat("scale", _scale);
 		_shader_ptr->setFloat("minZ", static_cast<float>(_minZ));
@@ -186,8 +191,10 @@ Heightmap::Heightmap(std::string filename): _filename(filename) {
     _shader_ptr->setFloat("plotLineAlongY_x", -99999.f);
 		_shader_ptr->setVec3("light_pos", glm::vec3(0.f, 0.f, 10.f));
 		_shader_ptr->setInt("lighting_enabled", 1);
-		_shader_ptr->setFloat("highlightingRadius", 0.05f);
+		_shader_ptr->setFloat("highlightingRadius", _highlightingRadius);
 		_shader_ptr->setInt("highlightingEnabled", 0);
+		_shader_ptr->setMat4("modelSpaceRot", _modelSpaceRot);
+		_shader_ptr->setFloat("originZ", _data[2]);
 		_shader_ptr->unuse();
 
 		/*Setup Framebuffer*/
@@ -269,13 +276,33 @@ float Heightmap::getSurfaceHeight(unsigned x, unsigned y, glm::mat4 projection,
 	_framebuffer_ptr->unbind();
 
 	if (defo_um != -1.f) {
-		return defo_um * _zRangeUm;
+		return defo_um * _zRangeUm - _zRangeUmOffset;
 	}
 	else {
 		return NOT_ON_SURFACE;
 	}
 }
 
+float Heightmap::getAverageSurfaceHeight(glm::vec2 xy) {
+	float total_height = 0.f;
+	unsigned num_values = 0;
+	float rad_sq = _highlightingRadius * _highlightingRadius;
+	for (size_t i = 0; i < _data.size() / 3; ++i) {
+		if (std::pow(_data[3 * i] - xy[0], 2) + std::pow(_data[3 * i + 1] - xy[1], 2) < rad_sq) {
+			if (_data[3 * i + 2] != BAD_Z_VALUE) {
+				total_height += _data[3 * i + 2];
+				++num_values;
+			}
+		}
+	}
+	if (num_values != 0) {
+		return total_height / static_cast<float>(num_values);
+	}
+	else {
+		return -1.f;
+	}
+}
+
 void Heightmap::updatePlotWindow(){
 	size_t slashpos = _filename.rfind("\\");
 	std::string drumname = _filename.substr(slashpos + 1, _filename.length() - slashpos - 1);
@@ -319,6 +346,10 @@ float Heightmap::zRangeUm() const {
 	return _zRangeUm;
 }
 
+void Heightmap::setZRangeUmOffset(float offset) {
+	_zRangeUmOffset += offset;
+}
+
 //Shader control
 void Heightmap::enableLighting() {
 	_shader_ptr->use();
@@ -345,12 +376,46 @@ void Heightmap::disableHighlighting() {
 	_shader_ptr->unuse();
 }
 
+void Heightmap::calculateNewZRange(glm::mat4 rot) {
+	float maxiZ = -99999.f;
+	float miniZ = 99999.f;
+	for (size_t i = 0; i < _data.size() / 3; ++i) {
+		if (_data[3 * i + 2] == BAD_Z_VALUE) {
+			continue;
+		}
+		else {
+			glm::vec4 newP = rot * glm::vec4(_data[3 * i], _data[3 * i + 1], _data[3 * i + 2], 1.f);
+			if (newP.z > maxiZ) {
+				maxiZ = newP.z;
+			}
+			if (newP.z < miniZ) {
+				miniZ = newP.z;
+			}
+		}
+	}
+	_maxZ = maxiZ;
+	_minZ = miniZ;
+	_shader_ptr->use();
+	_shader_ptr->setFloat("minZ", static_cast<float>(_minZ));
+	_shader_ptr->setFloat("maxZ", static_cast<float>(_maxZ));
+	_shader_ptr->unuse();
+}
+
+void Heightmap::setModelspaceRot(glm::mat4 rot) {
+	_modelSpaceRot = rot * _modelSpaceRot;
+	_shader_ptr->use();
+	_shader_ptr->setMat4("modelSpaceRot", _modelSpaceRot);
+	_shader_ptr->unuse();
+}
+
 void Heightmap::_plotHeightLineAlongX(const float y){
 	if(y != _last_plotAlongX_y){
 		_last_plotAlongX_y = y;
 		if(y > _maxY || y < _minY){
 			return;
 		}
+		//setup translation vector
+		float z_offset = _data[2];
 		//find correct i (row)
 		//TODO: This has to change when _data changes
 		size_t stride = 3;
@@ -369,7 +434,14 @@ void Heightmap::_plotHeightLineAlongX(const float y){
 		for(size_t j = 0; j < _Nx; ++j){
 			_plotAlongX_data_x[j] = _data[stride * j * _Ny + stride * i];
 			if (_data[stride * j * _Ny + stride * i + 2] != BAD_Z_VALUE) {
-				_plotAlongX_data_h[j] = _minZ + _zRangeUm * _data[stride * j * _Ny + stride * i + 2];
+				//transform data
+				float x = _data[stride * j * _Ny + stride * i];
+				float y = _data[stride * j * _Ny + stride * i + 1];
+				float z = _data[stride * j * _Ny + stride * i + 2];
+				glm::vec4 data(x, y, z - z_offset, 1.);
+				data = _modelSpaceRot * data;
+				float transformed_z = data.z + z_offset;
+				_plotAlongX_data_h[j] = _zRangeUm * (transformed_z - _minZ) / (_maxZ - _minZ) - _zRangeUmOffset;
 			}
 			else {
 				_plotAlongX_data_h[j] = NAN;
@@ -391,6 +463,8 @@ void Heightmap::_plotHeightLineAlongY(const float x){
 		if(x > _maxX || x < _minX){
 			return;
 		}
+		//setup translation vector
+		float z_offset = _data[2];
 		//find correct i (column)
 		//TODO: This has to change when _data changes
 		size_t stride = 3;
@@ -409,7 +483,14 @@ void Heightmap::_plotHeightLineAlongY(const float x){
 		for(size_t j = 0; j < _Ny; ++j){
 			_plotAlongY_data_y[j] = _data[stride * _Ny * i + stride * j + 1];
 			if (_data[stride * _Ny * i + stride * j + 2] != BAD_Z_VALUE) {
-				_plotAlongY_data_h[j] = _minZ + _zRangeUm * _data[stride * _Ny * i + stride * j + 2];
+				//transform data
+				float x = _data[stride * _Ny * i + stride * j];
+				float y = _data[stride * _Ny * i + stride * j + 1];
+				float z = _data[stride * _Ny * i + stride * j + 2];
+				glm::vec4 data(x, y, z - z_offset, 1.);
+				data = _modelSpaceRot * data;
+				float transformed_z = data.z + z_offset;
+				_plotAlongY_data_h[j] = _zRangeUm * (transformed_z - _minZ) / (_maxZ - _minZ) - _zRangeUmOffset;
 			}
 			else {
 				_plotAlongY_data_h[j] = NAN;