<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Centre of the Universe &#187; Tutorials</title>
	<atom:link href="http://www.sergemeunier.com/blog/category/tutorials/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sergemeunier.com/blog</link>
	<description>The musings of a mad software developer</description>
	<lastBuildDate>Tue, 01 Jun 2010 20:26:26 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Building a gravity simulator in O3D &#8211; Part 3</title>
		<link>http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-3/</link>
		<comments>http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-3/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 11:58:11 +0000</pubDate>
		<dc:creator>Serge Meunier</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Science]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[O3D]]></category>
		<category><![CDATA[Physics]]></category>

		<guid isPermaLink="false">http://www.sergemeunier.com/blog/?p=1684</guid>
		<description><![CDATA[If you missed part 1 and part 2 of this series go and check them out first.
Now that we have the physics engine, and are able to parse the input, slotting all of this into O3D is rather trivial.
All you need to do is create a standard O3D application, load the data from the input [...]


Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-2/' rel='bookmark' title='Permanent Link: Building a gravity simulator in O3D &#8211; Part 2'>Building a gravity simulator in O3D &#8211; Part 2</a> <small>In the last post, I introduced the physics engine for...</small></li>
<li><a href='http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-1/' rel='bookmark' title='Permanent Link: Building a gravity simulator in O3D &#8211; Part 1'>Building a gravity simulator in O3D &#8211; Part 1</a> <small>O3D allows you full reign to let your imagination loose...</small></li>
<li><a href='http://www.sergemeunier.com/blog/how-to-dump-a-javascript-object/' rel='bookmark' title='Permanent Link: How to dump a Javascript object'>How to dump a Javascript object</a> <small>When trying to debug Javascript, objects can be a real...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>If you missed <a href="http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-1">part 1</a> and <a href="http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-2">part 2</a> of this series go and check them out first.</p>
<p>Now that we have the physics engine, and are able to parse the input, slotting all of this into O3D is rather trivial.</p>
<p>All you need to do is create a standard O3D application, load the data from the input text into the relevant variables, set up the views and objects accordingly, and you are A for away.</p>
<p>In the app, I have used spheres to represent the objects which need to intereact with one another, but can literally be any object you want from cubes to X-wing fighters.</p>
<p>If you know a bit about O3D, then the only really interesting bit happens in the <em>renderCallback()</em> function. If you don&#8217;t, then go and have a look at my <a href="">o3d tutorial series</a> to learn how the O3D components all fit together.</p>
<p>What we do here, is call our physics engine to recalculate the positions of each object, and then loop through the objects setting up the transforms for each object to translate the object to the current position of the object.</p>
<pre name="code" class="Javascript">
function renderCallback(renderEvent) {
	for(var i = 0; i < calcsPerRender; i++){
		Gravity.calcNewPositions(objects, (renderEvent.elapsedTime * g_timeMultiplier) / calcsPerRender);
	}
	for(var i = 0; i < objects.length; i++) {
		g_objectTransforms[i].identity();
		g_objectTransforms[i].translate(objects[i].position);
	}
}
</pre>
<p><span id="more-1684"></span><br />
Here is the full code for the O3D component</p>
<pre name="code" class="Javascript">
function trim(str, chars) {
	return ltrim(rtrim(str, chars), chars);
}

function ltrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

function rtrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

o3djs.require('o3djs.util');
o3djs.require('o3djs.math');
o3djs.require('o3djs.rendergraph');
o3djs.require('o3djs.effect');
o3djs.require('o3djs.primitives');

var scalingFactor = 1e10;
var calcsPerRender = 100;
var g_timeMultiplier = 8000;
var objects = [];

// Events
// Run the init() function once the page has finished loading.
// Run the uninit() function when the page has is unloaded.
window.onload = init;
window.onunload = uninit;

// global variables
var g_o3d;
var g_client;
var g_pack;
var g_3dRoot;
var g_viewInfo;
var g_objectTransforms;

var g_camera = {
	eye: [0, 0, -100],
	target: [0, 0, 0],
	up: [0, 1, 0]};

var g_lightPosition = [0, 0, 100];
//Creates the client area.
function init() {
	o3djs.util.makeClients(initStep2);
}

function loadData(){

	var data = document.getElementById('siminput').value;
	data = data.split(';');

	scalingFactor = parseFloat(data[0].split(':')[1]);
	calcsPerRender = parseInt(data[1].split(':')[1]);
	g_timeMultiplier = parseInt(data[2].split(':')[1]);	

	var item = data[3].split(':')[1].split(',');
	g_camera['eye'] = [parseFloat(item[0]), parseFloat(item[1]), parseFloat(item[2])];	

	item = data[4].split(':')[1].split(',');
	g_camera['target'] = [parseFloat(item[0]), parseFloat(item[1]), parseFloat(item[2])];			

	item = data[5].split(':')[1].split(',');
	g_camera['up'] = [parseFloat(item[0]), parseFloat(item[1]), parseFloat(item[2])];		

	item = data[6].split(':')[1].split(',');
	g_lightPosition = [parseFloat(item[0]), parseFloat(item[1]), parseFloat(item[2])];			

	Gravity.scaleConstantForLenth(scalingFactor);

	var objectCount = 0;
	objects = [];
	for(var i = 8; i < data.length; i++){
		if ((i-8) % 5 == 0){
			var line = data[i].split(':');

			if (trim(line[0]) == 'end'){
				break;
			}

			var item = line[1].split(',');
			objects[objectCount] = new PhysicsObject();
			objects[objectCount].position = [parseFloat(item[0]) / scalingFactor, parseFloat(item[1]) / scalingFactor, parseFloat(item[2]) / scalingFactor];

			line = data[i+1].split(':');
			item = line[1].split(',');
			objects[objectCount].velocity = [parseFloat(item[0]) / scalingFactor, parseFloat(item[1]) / scalingFactor, parseFloat(item[2]) / scalingFactor];

			line = data[i+2].split(':');
			item = line[1].split(',');
			objects[objectCount].color = [parseFloat(item[0]), parseFloat(item[1]), parseFloat(item[2]), parseFloat(item[3])];

			line = data[i+3].split(':');
			objects[objectCount].radius = parseFloat(line[1]);

			line = data[i+4].split(':');
			objects[objectCount].mass = parseFloat(line[1]);

			objectCount++;
		}
	}
	setupScene();
}

function createPhongMaterial(baseColor) {

  var material = g_pack.createObject('Material');

  o3djs.effect.attachStandardShader(
      g_pack, material, g_lightPosition, 'phong');

  material.drawList = g_viewInfo.performanceDrawList;

  material.getParam('emissive').value = [0, 0, 0, 1];
  material.getParam('ambient').value = o3djs.math.mulScalarVector(0.1, baseColor);
  material.getParam('diffuse').value = o3djs.math.mulScalarVector(0.9, baseColor);
  material.getParam('specular').value = [.2, .2, .2, 1];
  material.getParam('shininess').value = 20;
  return material;
}

function createSpheres(){
	var sphere = [];
	g_objectTransforms = [];
	for(var i = 0; i < objects.length; i++){
		sphere[i] = o3djs.primitives.createSphere(
		  g_pack,
		  createPhongMaterial(objects[i].color),
		  objects[i].radius,   // Radius of the sphere.
		  30,    // Number of meridians.
		  20);    // Number of parallels.

		g_objectTransforms[i] = g_pack.createObject('Transform');
		g_objectTransforms[i].addShape(sphere[i]);
		g_objectTransforms[i].translate(objects[i].position);
		g_objectTransforms[i].parent = g_3dRoot;
	}

}

function setupScene(){
    // Create a pack to manage the objects created.
    g_pack = g_client.createPack();

	//Create a root transform
	g_3dRoot = g_pack.createObject('Transform');

    // Create the render graph for a view.
    g_viewInfo = o3djs.rendergraph.createBasicView(
	   g_pack,
	   g_3dRoot,
	   g_client.renderGraphRoot);

	// Set up a simple orthographic view.
    g_viewInfo.drawContext.projection = o3djs.math.matrix4.perspective(
	   o3djs.math.degToRad(30), // 30 degree fov.
	   g_client.width / g_client.height,
	   1,                  // Near plane.
	   5000);              // Far plane.

    // Set up our view transformation to look towards the world origin
    // where the cube is located.
    g_viewInfo.drawContext.view = o3djs.math.matrix4.lookAt(g_camera.eye,
											 g_camera.target,
											 g_camera.up);
	g_viewInfo.clearBuffer.clearColor = [0, 0, 0, 1]; 												

	createSpheres();

	g_client.setRenderCallback(renderCallback);	

}

//Initializes O3D.
function initStep2(clientElements) {
	// Initializes global variables and libraries.
	g_client = clientElements[0].client;
	g_o3d = clientElements[0].o3d;

	// Initialize O3D libraries.
	o3djs.base.init(clientElements[0]);

	loadData();
}

//Removes any callbacks so they don't get called after the page has unloaded.
function uninit() {
	if (g_client) {
		g_client.cleanup();
	}
}

//This method gets called every time O3D renders a frame.
//Here's where we update the cube's transform to make it spin.
function renderCallback(renderEvent) {
	for(var i = 0; i < calcsPerRender; i++){
		Gravity.calcNewPositions(objects, (renderEvent.elapsedTime * g_timeMultiplier) / calcsPerRender);
	}
	for(var i = 0; i < objects.length; i++) {
		g_objectTransforms[i].identity();
		g_objectTransforms[i].translate(objects[i].position);
	}
}
</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.sergemeunier.com%2Fblog%2Fbuilding-a-gravity-simulator-in-o3d-part-3%2F&amp;linkname=Building%20a%20gravity%20simulator%20in%20O3D%20%26%238211%3B%20Part%203"><img src="http://www.sergemeunier.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-2/' rel='bookmark' title='Permanent Link: Building a gravity simulator in O3D &#8211; Part 2'>Building a gravity simulator in O3D &#8211; Part 2</a> <small>In the last post, I introduced the physics engine for...</small></li>
<li><a href='http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-1/' rel='bookmark' title='Permanent Link: Building a gravity simulator in O3D &#8211; Part 1'>Building a gravity simulator in O3D &#8211; Part 1</a> <small>O3D allows you full reign to let your imagination loose...</small></li>
<li><a href='http://www.sergemeunier.com/blog/how-to-dump-a-javascript-object/' rel='bookmark' title='Permanent Link: How to dump a Javascript object'>How to dump a Javascript object</a> <small>When trying to debug Javascript, objects can be a real...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building a gravity simulator in O3D &#8211; Part 2</title>
		<link>http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-2/</link>
		<comments>http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-2/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 11:47:14 +0000</pubDate>
		<dc:creator>Serge Meunier</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Science]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[O3D]]></category>
		<category><![CDATA[Physics]]></category>

		<guid isPermaLink="false">http://www.sergemeunier.com/blog/?p=1680</guid>
		<description><![CDATA[In the last post, I introduced the physics engine for the gravity simulator. Now let us look at the scripting engine.
There needs to be an easy way to be able to enter the data into the application, so that you can fiddle with different scenarios instead of hardcoding values in.
The way the application does it, [...]


Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-3/' rel='bookmark' title='Permanent Link: Building a gravity simulator in O3D &#8211; Part 3'>Building a gravity simulator in O3D &#8211; Part 3</a> <small>If you missed part 1 and part 2 of this...</small></li>
<li><a href='http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-1/' rel='bookmark' title='Permanent Link: Building a gravity simulator in O3D &#8211; Part 1'>Building a gravity simulator in O3D &#8211; Part 1</a> <small>O3D allows you full reign to let your imagination loose...</small></li>
<li><a href='http://www.sergemeunier.com/blog/how-to-dump-a-javascript-object/' rel='bookmark' title='Permanent Link: How to dump a Javascript object'>How to dump a Javascript object</a> <small>When trying to debug Javascript, objects can be a real...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>In the last <a href="http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-1">post</a>, I introduced the physics engine for the gravity simulator. Now let us look at the scripting engine.</p>
<p>There needs to be an easy way to be able to enter the data into the application, so that you can fiddle with different scenarios instead of hardcoding values in.</p>
<p>The way the application does it, is by adding a text area into the HTML page containing the text needed to set the variables</p>
<pre name="code" class="Javascript">
<form>
<div width="100%">
<input type="button" id="calc_button" value="Calc" onclick="loadData();"/>&nbsp;&nbsp;
				</div>
<div>

					<textarea id="siminput" cols="40" rows="20">scaling factor :1e10;
calculations per render :100;
time multiplier :1000000;
camera position:0,0,100;
camera looking at:0,0,0;
camera up:0,1,0;
light position:0,0,100;
start;
position	:0,0,0;
velocity	:0,0,0;
color		:1,0,0,1;
radius		:2;
mass		:1.9891e30;
position	:1.49598e11,0,0;
velocity	:0,29800,0;
color		:0,1,0,1;
radius		:1;
mass		:5.9742e24;
position	:4.49598e10,0,0;
velocity	:0,60000,0;
color		:1,1,0,1;
radius		:0.8;
mass		:5.9742e22;
position	:-10.49598e10,0,0;
velocity	:0,-28800,0;
color		:1,0,1,1;
radius		:0.5;
mass		:5.9742e20;
end;
					</textarea>
				</div>
</form>
</pre>
<p><span id="more-1680"></span></p>
<p>The format is very strict and the order of variables is important. Each line contains one value matching up to a variable to set.<br />
Between the start and end tags, the objects are defined, and there can be any number of items defined here.</p>
<p>The scaling factor determines how much to scale the distances by for our simulation.<br />
The number of calculations per render sets up how many times you need to calculate the gravity calcs for each render of the objects. The higher this number, the more accurate the result, but the slower the render.<br />
The time multiplier determines how much to speed up time. The higher this value, the faster the simulation will run, and the calculations will also be rather less accurate as well.</p>
<p>The next three values determine the camera setup within O3D and are arrays of 3 numbers each.</p>
<p>The last value is the location of the light used for the lighting of the objects.</p>
<p>Now, for each object, we need to specify the position, velocity, color, radius and mass. There can be any number of objects specified but all five fields need to be there though.</p>
<p>Now, in the Javascript, we need to process the text input. This is simply done by splitting up the text using the ; character to split lines up and then assigning the relevant values to the correct variables, and building up an array of objects we want to render.</p>
<p>We also need a few trimming functions to use for our text to get rid of whitespace.</p>
<p>In the next part, we are going to look at putting this together with the physics engine into the O3D application.</p>
<pre name="code" class="Javascript">
function trim(str, chars) {
	return ltrim(rtrim(str, chars), chars);
}

function ltrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

function rtrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}
function loadData(){

	var data = document.getElementById('siminput').value;
	data = data.split(';');

	scalingFactor = parseFloat(data[0].split(':')[1]);
	calcsPerRender = parseInt(data[1].split(':')[1]);
	g_timeMultiplier = parseInt(data[2].split(':')[1]);	

	var item = data[3].split(':')[1].split(',');
	g_camera['eye'] = [parseFloat(item[0]), parseFloat(item[1]), parseFloat(item[2])];	

	item = data[4].split(':')[1].split(',');
	g_camera['target'] = [parseFloat(item[0]), parseFloat(item[1]), parseFloat(item[2])];			

	item = data[5].split(':')[1].split(',');
	g_camera['up'] = [parseFloat(item[0]), parseFloat(item[1]), parseFloat(item[2])];		

	item = data[6].split(':')[1].split(',');
	g_lightPosition = [parseFloat(item[0]), parseFloat(item[1]), parseFloat(item[2])];			

	Gravity.scaleConstantForLenth(scalingFactor);

	var objectCount = 0;
	objects = [];
	for(var i = 8; i < data.length; i++){
		if ((i-8) % 5 == 0){
			var line = data[i].split(':');

			if (trim(line[0]) == 'end'){
				break;
			}

			var item = line[1].split(',');
			objects[objectCount] = new PhysicsObject();
			objects[objectCount].position = [parseFloat(item[0]) / scalingFactor, parseFloat(item[1]) / scalingFactor, parseFloat(item[2]) / scalingFactor];

			line = data[i+1].split(':');
			item = line[1].split(',');
			objects[objectCount].velocity = [parseFloat(item[0]) / scalingFactor, parseFloat(item[1]) / scalingFactor, parseFloat(item[2]) / scalingFactor];

			line = data[i+2].split(':');
			item = line[1].split(',');
			objects[objectCount].color = [parseFloat(item[0]), parseFloat(item[1]), parseFloat(item[2]), parseFloat(item[3])];

			line = data[i+3].split(':');
			objects[objectCount].radius = parseFloat(line[1]);

			line = data[i+4].split(':');
			objects[objectCount].mass = parseFloat(line[1]);

			objectCount++;
		}
	}
	setupScene();
}
</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.sergemeunier.com%2Fblog%2Fbuilding-a-gravity-simulator-in-o3d-part-2%2F&amp;linkname=Building%20a%20gravity%20simulator%20in%20O3D%20%26%238211%3B%20Part%202"><img src="http://www.sergemeunier.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-3/' rel='bookmark' title='Permanent Link: Building a gravity simulator in O3D &#8211; Part 3'>Building a gravity simulator in O3D &#8211; Part 3</a> <small>If you missed part 1 and part 2 of this...</small></li>
<li><a href='http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-1/' rel='bookmark' title='Permanent Link: Building a gravity simulator in O3D &#8211; Part 1'>Building a gravity simulator in O3D &#8211; Part 1</a> <small>O3D allows you full reign to let your imagination loose...</small></li>
<li><a href='http://www.sergemeunier.com/blog/how-to-dump-a-javascript-object/' rel='bookmark' title='Permanent Link: How to dump a Javascript object'>How to dump a Javascript object</a> <small>When trying to debug Javascript, objects can be a real...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building a gravity simulator in O3D &#8211; Part 1</title>
		<link>http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-1/</link>
		<comments>http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-1/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 11:35:05 +0000</pubDate>
		<dc:creator>Serge Meunier</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Science]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[O3D]]></category>
		<category><![CDATA[Physics]]></category>

		<guid isPermaLink="false">http://www.sergemeunier.com/blog/?p=1676</guid>
		<description><![CDATA[O3D allows you full reign to let your imagination loose in the 3D realm. As such, I thought it would be a great idea to be able to write a gravity simulator in the 3D world, which would support multiple bodies interacting with each other. You can see the simulator in action here on my [...]


Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-2/' rel='bookmark' title='Permanent Link: Building a gravity simulator in O3D &#8211; Part 2'>Building a gravity simulator in O3D &#8211; Part 2</a> <small>In the last post, I introduced the physics engine for...</small></li>
<li><a href='http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-3/' rel='bookmark' title='Permanent Link: Building a gravity simulator in O3D &#8211; Part 3'>Building a gravity simulator in O3D &#8211; Part 3</a> <small>If you missed part 1 and part 2 of this...</small></li>
<li><a href='http://www.sergemeunier.com/blog/vectors-in-c-sharp/' rel='bookmark' title='Permanent Link: Vectors in C#'>Vectors in C#</a> <small>A vector is simply a 1-dimensional array of numbers that...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>O3D allows you full reign to let your imagination loose in the 3D realm. As such, I thought it would be a great idea to be able to write a gravity simulator in the 3D world, which would support multiple bodies interacting with each other. You can see the simulator in action here on my <a href="http://www.sergemeunier.com/gravity/index.html">site</a>.</p>
<p>The gravity simulator is fully written in JavaScript, and is made up of the physics library, the O3D application to render the objects and the scripting engine.</p>
<p>The physics library provides the classes necessary to keep track of all the data we need for each object we want to represent, as well as the classes that will do our calculations, and is what we will cover in this part of the series.</p>
<p>The O3D application takes care of all the rendering, as well as supplying the data to the physics library and then renders the results.</p>
<p>The scripting engine parses the input text which is used to initialise all the O3D variables and objects we want to draw.<br />
<span id="more-1676"></span></p>
<p>So, now on to discussing the actual physics engine for gravity.</p>
<p>The first thing we need is an object that contains all the information we need to calculate gravity for a particular body in space. This is given in the <em>PhysicsObject</em> class.</p>
<pre name="code" class="Javascript">
PhysicsObject = function(){
	this.position = [0,0,0];
	this.velocity = [0,0,0];
	this.color = [1,1,1,1];
	this.radius = 1;
	this.mass = 1;

	this.setProperties = function(position, velocity, color, radius, mass) {
		this.position = position;
		this.velocity = velocity;
		this.color = color;
		this.radius = radius;
		this.mass = mass;
	};
}</pre>
<p>We also need to have a class that takes care of vector operations such as arithmetic and multiplication. O3D does come with its own vector library, but to keep the actual physics engine as separate from O3D as possible, we need a basic class to do this.<br />
In this implementation, vectors are simply an array of numbers, and then you can use functions inside this class to do the necessary operations to the vector arrays</p>
<pre name="code" class="Javascript">
Vector = new function(){

	//Add two vectors
	this.add = function(a, b){
		var result = [0,0,0];
		if (a.length != b.length){
			throw "Vectors need to be the same size";
		}

		for(var i = 0; i < a.length; i++) {
			result[i] = a[i] + b[i];
		}
		return result;
	}

	//Subtract two vectors
	this.subtract = function(a, b){
		var result = [0,0,0];
		if (a.length != b.length){
			throw "Vectors need to be the same size";
		}

		for(var i = 0; i < a.length; i++) {
			result[i] = a[i] - b[i];
		}
		return result;
	}

	//Add scalar to vector
	this.addScalar = function(a, scalar){
		var result = [0,0,0];

		for(var i = 0; i < a.length; i++) {
			result[i] = a[i] + scalar;
		}
		return result;
	}

	//Subtract scalar to vector
	this.subtractScalar = function(a, scalar){
		var result = [0,0,0];

		for(var i = 0; i < a.length; i++) {
			result[i] = a[i] - scalar;
		}
		return result;
	}

	//multiply scalar with vector
	this.multiplyScalar = function(a, scalar){
		var result = [0,0,0];

		for(var i = 0; i < a.length; i++) {
			result[i] = a[i] * scalar;
		}
		return result;
	}

	//divide vector with scalar
	this.divideScalar = function(a, scalar){
		var result = [0,0,0];

		for(var i = 0; i < a.length; i++) {
			result[i] = a[i] / scalar;
		}
		return result;
	}

	//Get length of vector
	this.length = function(a){
		var result = 0;

		for(var i = 0; i < a.length; i++) {
			result += (a[i] * a[i]);
		}
		result = Math.sqrt(result);
		return result;
	}

	this.unitVector = function(a){
		var length = this.length(a);
		var unit = this.divideScalar(a, length);
		return unit;
	}

	this.distance = function(a, b){
		var result = this.subtract(a - b);
		result = this.length(result);
		return result;
	}
}
</pre>
<p>The last class does the actual gravity calculation. </p>
<p>What you do is pass an array of objects which you want to calc the interactions for, and the time elapsed since the last calculation to the <em>calcNewPositions()</em> function</p>
<p>The function will loop through each object, and first adjust the velocity of the object based on the gravitational effect of each of the other objects based on the formula <em>Force = G * mass1 * mass2 / distance squared</em>. The change in velocity is found by getting the acceleration applied to the object by the force and then adjusting accordingly. </p>
<p>The effect of each successive object on an object is merely the sum of changes caused by each object on an object.</p>
<p>Once you have found all the velocity adjustments you need, you then adjust the positions of each object based on their new velocities.</p>
<p>Now we are done here, and the rendering engine can take over by rendering the objects in the correct place.</p>
<p>One addition function needed here is the <em>scaleConstantForLenth()</em> function, which allows you to adjust the gravitational constant G, depending on what units you are using to measure length.</p>
<pre name="code" class="Javascript">
//----------------------------------------------------
// Gravity
// A class to implement the law of universal Gravitation
// F = Gm1m2/r^2
//----------------------------------------------------
Gravity = new function(){
	this.G = 6.673e-11; //6.673 x 10^-11 m^3 kg^-1 s^-2

	this.scaleConstantForLenth = function(scalingFactor){
		Gravity.G = 6.673e-11 / (scalingFactor * scalingFactor * scalingFactor);
	}
	this.calcGravitationalForce = function(mass1, mass2, distance){
		var force = (Gravity.G * mass1 * mass2) / (distance * distance);
		return force;
	}

	this.calcGravitationalForceVector = function(mass1, mass2, distance, directionVector){
		var force = (Gravity.G * mass1 * mass2) / (distance * distance);

		force = Vector.multiplyScalar(directionVector, force);
		return force;
	}

	this.calcAccelerationVector = function(forceVector, mass){
		var accelerationVector = Vector.divideScalar(forceVector, mass);
		return accelerationVector;
	}

	this.calcNewPositions = function(objects, timeElapsed){
		for(var i = 0; i < objects.length - 1; i++){
			for(var j = i + 1; j < objects.length; j++){
				var distanceVector = Vector.subtract(objects[j].position, objects[i].position);
				var directionVector = Vector.unitVector(distanceVector);
				var forceVector = Gravity.calcGravitationalForceVector(objects[i].mass, objects[j].mass, Vector.length(distanceVector), directionVector);

				//update first object
				var accelerationVector = Gravity.calcAccelerationVector(forceVector, objects[i].mass);
				objects[i].velocity = Vector.add(objects[i].velocity, Vector.multiplyScalar(accelerationVector, timeElapsed));

				//update second object
				forceVector = Vector.multiplyScalar(forceVector, -1);
				var accelerationVector = Gravity.calcAccelerationVector(forceVector, objects[j].mass);
				objects[j].velocity = Vector.add(objects[j].velocity, Vector.multiplyScalar(accelerationVector, timeElapsed));
			}
		}

		for(var i = 0; i < objects.length; i++){
			var movement = Vector.multiplyScalar(objects[i].velocity, timeElapsed);
			objects[i].position = Vector.add(objects[i].position, movement);
		}
	}

}
</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.sergemeunier.com%2Fblog%2Fbuilding-a-gravity-simulator-in-o3d-part-1%2F&amp;linkname=Building%20a%20gravity%20simulator%20in%20O3D%20%26%238211%3B%20Part%201"><img src="http://www.sergemeunier.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-2/' rel='bookmark' title='Permanent Link: Building a gravity simulator in O3D &#8211; Part 2'>Building a gravity simulator in O3D &#8211; Part 2</a> <small>In the last post, I introduced the physics engine for...</small></li>
<li><a href='http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-3/' rel='bookmark' title='Permanent Link: Building a gravity simulator in O3D &#8211; Part 3'>Building a gravity simulator in O3D &#8211; Part 3</a> <small>If you missed part 1 and part 2 of this...</small></li>
<li><a href='http://www.sergemeunier.com/blog/vectors-in-c-sharp/' rel='bookmark' title='Permanent Link: Vectors in C#'>Vectors in C#</a> <small>A vector is simply a 1-dimensional array of numbers that...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sergemeunier.com/blog/building-a-gravity-simulator-in-o3d-part-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Image Processing in C#: Decreasing the colour depth</title>
		<link>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-decreasing-the-colour-depth/</link>
		<comments>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-decreasing-the-colour-depth/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 05:48:21 +0000</pubDate>
		<dc:creator>Serge Meunier</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Image processing]]></category>

		<guid isPermaLink="false">http://www.sergemeunier.com/blog/?p=1592</guid>
		<description><![CDATA[Decreasing the colour depth involves converting colour values to standard values.
Specifying an offset, preferably a value evenly divisible by 256, such as 16, 24 or 32, we then need to make sure that the red, green and blue components&#8217; values get rounded off to multiples of this offset.
For example, using an offset of 16, value [...]


Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-colour-filters/' rel='bookmark' title='Permanent Link: Image Processing in C#: Colour filters'>Image Processing in C#: Colour filters</a> <small>Implementing a colour filter is a rather simple affair. All...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-contrast/' rel='bookmark' title='Permanent Link: Image Processing in C#: Contrast'>Image Processing in C#: Contrast</a> <small>Contrast in a picture is a measure of how close...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-converting-an-image-to-greyscale/' rel='bookmark' title='Permanent Link: Image Processing in C#: Converting an image to greyscale'>Image Processing in C#: Converting an image to greyscale</a> <small>Converting an image to greyscale is a relatively easy effect...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Decreasing the colour depth involves converting colour values to standard values.</p>
<p>Specifying an offset, preferably a value evenly divisible by 256, such as 16, 24 or 32, we then need to make sure that the red, green and blue components&#8217; values get rounded off to multiples of this offset.</p>
<p>For example, using an offset of 16, value colour values would be 0, 15, 31, 47,&#8230;&#8230;, 255. and all values would need to be rounded off to these values for each of the colour components.</p>
<p>To be able to do this, we take the component value, and then add half of the offset to the value. We then subtract the modulo of this value and the offset. This then gives values along the lines of 0, 16, 32, &#8230;., 256, so we will need to subtract 1 from this, but will need to put in a correction for 0, since that value needs to remain as it is.<br />
<div id="attachment_1593" class="wp-caption aligncenter" style="width: 490px"><img src="http://www.sergemeunier.com/blog/wp-content/uploads/2010/01/Garfield-DecreaseColorDepth.jpg" alt="Decreasing the colour depth using an offset of 16" title="Decreasing the colour depth using an offset of 16" width="480" height="180" class="size-full wp-image-1593" /><p class="wp-caption-text">Decreasing the colour depth using an offset of 16</p></div><br />
You can download the full code for the sample application which contains code for all the image effects covered in the series <a href="http://www.sergemeunier.com/downloads/ImageProcessor.zip">here</a>.</p>
<pre name="code" class="C-Sharp">
public void ApplyDecreaseColourDepth(int offset)
{
    int A, R, G, B;
    Color pixelColor;

    for (int y = 0; y < bitmapImage.Height; y++)
    {
        for (int x = 0; x < bitmapImage.Width; x++)
        {
            pixelColor = bitmapImage.GetPixel(x, y);
            A = pixelColor.A;
            R = ((pixelColor.R + (offset / 2)) - ((pixelColor.R + (offset / 2)) % offset) - 1);
            if (R < 0)
            {
                R = 0;
            }
            G = ((pixelColor.G + (offset / 2)) - ((pixelColor.G + (offset / 2)) % offset) - 1);
            if (G < 0)
            {
                G = 0;
            }
            B = ((pixelColor.B + (offset / 2)) - ((pixelColor.B + (offset / 2)) % offset) - 1);
            if (B < 0)
            {
                B = 0;
            }
            bitmapImage.SetPixel(x, y, Color.FromArgb(A, R, G, B));
        }
    }

}
</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.sergemeunier.com%2Fblog%2Fimage-processing-in-c-sharp-decreasing-the-colour-depth%2F&amp;linkname=Image%20Processing%20in%20C%23%3A%20Decreasing%20the%20colour%20depth"><img src="http://www.sergemeunier.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-colour-filters/' rel='bookmark' title='Permanent Link: Image Processing in C#: Colour filters'>Image Processing in C#: Colour filters</a> <small>Implementing a colour filter is a rather simple affair. All...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-contrast/' rel='bookmark' title='Permanent Link: Image Processing in C#: Contrast'>Image Processing in C#: Contrast</a> <small>Contrast in a picture is a measure of how close...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-converting-an-image-to-greyscale/' rel='bookmark' title='Permanent Link: Image Processing in C#: Converting an image to greyscale'>Image Processing in C#: Converting an image to greyscale</a> <small>Converting an image to greyscale is a relatively easy effect...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-decreasing-the-colour-depth/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Image Processing in C#: Getting that old-time effect with sepia</title>
		<link>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-getting-that-old-time-effect-with-sepia/</link>
		<comments>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-getting-that-old-time-effect-with-sepia/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 05:38:22 +0000</pubDate>
		<dc:creator>Serge Meunier</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Image processing]]></category>

		<guid isPermaLink="false">http://www.sergemeunier.com/blog/?p=1588</guid>
		<description><![CDATA[Back in the old days, and here I am talking about the 19th century old days, it was very common to apply a sepia tinting to photographs. This was a chemical process, which preserved the photos for longer, although it was also used for its aesthetic appeal.
These days, with digital photograpy, we don&#8217;t need to [...]


Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-converting-an-image-to-greyscale/' rel='bookmark' title='Permanent Link: Image Processing in C#: Converting an image to greyscale'>Image Processing in C#: Converting an image to greyscale</a> <small>Converting an image to greyscale is a relatively easy effect...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-colour-filters/' rel='bookmark' title='Permanent Link: Image Processing in C#: Colour filters'>Image Processing in C#: Colour filters</a> <small>Implementing a colour filter is a rather simple affair. All...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-adjusting-the-brightness/' rel='bookmark' title='Permanent Link: Image Processing in C#: Adjusting the brightness'>Image Processing in C#: Adjusting the brightness</a> <small>To increase the brightness of an image, all you need...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Back in the old days, and here I am talking about the 19th century old days, it was very common to apply a sepia tinting to photographs. This was a chemical process, which preserved the photos for longer, although it was also used for its aesthetic appeal.</p>
<p>These days, with digital photograpy, we don&#8217;t need to preserve photos like in those early days, but it still does give a nice warm tone to a photo, and is great for making a modern photo appear old-fashioned.</p>
<p>Converting a photo to sepia is a relatively easy effect. </p>
<p>For each pixel in the image, we first convert the pixel to greyscale. We then add a value to the green component, and double that value to the red component to give the sepia effect.</p>
<p>The depth of the sepia effect is determined by this value, which we pass here as a parameter. A value of 0 will give a standard greyscale image.<br />
<div id="attachment_1589" class="wp-caption aligncenter" style="width: 490px"><img src="http://www.sergemeunier.com/blog/wp-content/uploads/2010/01/Garfield-Sepia.jpg" alt="Applying a Sepia value of 20" title="Applying a Sepia value of 20" width="480" height="180" class="size-full wp-image-1589" /><p class="wp-caption-text">Applying a Sepia value of 20</p></div><br />
You can download the full code for the sample application which contains code for all the image effects covered in the series <a href="http://www.sergemeunier.com/downloads/ImageProcessor.zip">here</a>.</p>
<pre name="code" class="C-Sharp">
public void ApplySepia(int depth)
{
    int A, R, G, B;
    Color pixelColor;

    for (int y = 0; y < bitmapImage.Height; y++)
    {
        for (int x = 0; x < bitmapImage.Width; x++)
        {
            pixelColor = bitmapImage.GetPixel(x, y);
            A = pixelColor.A;
            R = (int)((0.299 * pixelColor.R) + (0.587 * pixelColor.G) + (0.114 * pixelColor.B));
            G = B = R;

            R += (depth * 2);
            if (R > 255)
            {
                R = 255;
            }
            G += depth;
            if (G > 255)
            {
                G = 255;
            }

            bitmapImage.SetPixel(x, y, Color.FromArgb(A, R, G, B));
        }
    }
}
</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.sergemeunier.com%2Fblog%2Fimage-processing-in-c-sharp-getting-that-old-time-effect-with-sepia%2F&amp;linkname=Image%20Processing%20in%20C%23%3A%20Getting%20that%20old-time%20effect%20with%20sepia"><img src="http://www.sergemeunier.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-converting-an-image-to-greyscale/' rel='bookmark' title='Permanent Link: Image Processing in C#: Converting an image to greyscale'>Image Processing in C#: Converting an image to greyscale</a> <small>Converting an image to greyscale is a relatively easy effect...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-colour-filters/' rel='bookmark' title='Permanent Link: Image Processing in C#: Colour filters'>Image Processing in C#: Colour filters</a> <small>Implementing a colour filter is a rather simple affair. All...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-adjusting-the-brightness/' rel='bookmark' title='Permanent Link: Image Processing in C#: Adjusting the brightness'>Image Processing in C#: Adjusting the brightness</a> <small>To increase the brightness of an image, all you need...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-getting-that-old-time-effect-with-sepia/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Image Processing in C#: Embossing</title>
		<link>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-embossing/</link>
		<comments>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-embossing/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 05:52:03 +0000</pubDate>
		<dc:creator>Serge Meunier</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Image processing]]></category>

		<guid isPermaLink="false">http://www.sergemeunier.com/blog/?p=1584</guid>
		<description><![CDATA[One of the most striking effects to apply to an image is embossing. This is effect is a form of edge-detection, and is also done using convolution, which you can read more about on my post on Smoothing using convolution.
The convolution grid we use in embossing is a little different to the others we have [...]


Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-sharpening-the-image/' rel='bookmark' title='Permanent Link: Image Processing in C#: Sharpening the image'>Image Processing in C#: Sharpening the image</a> <small>Sharpening an image is merely the inverse of what we...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-smoothing-using-convolution/' rel='bookmark' title='Permanent Link: Image Processing in C#: Smoothing using convolution'>Image Processing in C#: Smoothing using convolution</a> <small>Smoothing, which is just a type of blurring is based...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-applying-a-mean-removal/' rel='bookmark' title='Permanent Link: Image Processing in C#: Applying a mean removal'>Image Processing in C#: Applying a mean removal</a> <small>Another type of sharpening effect is mean removal. It works...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>One of the most striking effects to apply to an image is embossing. This is effect is a form of edge-detection, and is also done using convolution, which you can read more about on my post on <a href="http://www.sergemeunier.com/blog/image-processing-in-c-sharp-smoothing-using-convolution/">Smoothing using convolution</a>.</p>
<p>The convolution grid we use in embossing is a little different to the others we have looked at so far. It has an offset of 127, and a fixed factor of 4. The offset makes the the image appear on average as a medium gray.</p>
<p>The grid we will use then is</p>
<table border='1'>
<tr>
<td>-1</td>
<td>0</td>
<td>-1</td>
</tr>
<tr>
<td>0</td>
<td>4</td>
<td>0</td>
</tr>
<tr>
<td>-1</td>
<td>0</td>
<td>-1</td>
</tr>
</table>
<p><div id="attachment_1585" class="wp-caption aligncenter" style="width: 490px"><img src="http://www.sergemeunier.com/blog/wp-content/uploads/2010/01/Garfield-Emboss.jpg" alt="Embossing" title="Embossing" width="480" height="180" class="size-full wp-image-1585" /><p class="wp-caption-text">Embossing</p></div><br />
You can download the full code for the sample application which contains code for all the image effects covered in the series <a href="http://www.sergemeunier.com/downloads/ImageProcessor.zip">here</a>.</p>
<pre name="code" class="C-Sharp">
public void ApplyEmboss(double weight)
{
    ConvolutionMatrix matrix = new ConvolutionMatrix(3);
    matrix.SetAll(1);
    matrix.Matrix[0, 0] = -1;
    matrix.Matrix[1, 0] = 0;
    matrix.Matrix[2, 0] = -1;
    matrix.Matrix[0, 1] = 0;
    matrix.Matrix[1, 1] = weight;
    matrix.Matrix[2, 1] = 0;
    matrix.Matrix[0, 2] = -1;
    matrix.Matrix[1, 2] = 0;
    matrix.Matrix[2, 2] = -1;
    matrix.Factor = 4;
    matrix.Offset = 127;
    bitmapImage = Convolution3x3(bitmapImage, matrix);

}
</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.sergemeunier.com%2Fblog%2Fimage-processing-in-c-sharp-embossing%2F&amp;linkname=Image%20Processing%20in%20C%23%3A%20Embossing"><img src="http://www.sergemeunier.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-sharpening-the-image/' rel='bookmark' title='Permanent Link: Image Processing in C#: Sharpening the image'>Image Processing in C#: Sharpening the image</a> <small>Sharpening an image is merely the inverse of what we...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-smoothing-using-convolution/' rel='bookmark' title='Permanent Link: Image Processing in C#: Smoothing using convolution'>Image Processing in C#: Smoothing using convolution</a> <small>Smoothing, which is just a type of blurring is based...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-applying-a-mean-removal/' rel='bookmark' title='Permanent Link: Image Processing in C#: Applying a mean removal'>Image Processing in C#: Applying a mean removal</a> <small>Another type of sharpening effect is mean removal. It works...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-embossing/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Image Processing in C#: Applying a mean removal</title>
		<link>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-applying-a-mean-removal/</link>
		<comments>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-applying-a-mean-removal/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 05:42:58 +0000</pubDate>
		<dc:creator>Serge Meunier</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Image processing]]></category>

		<guid isPermaLink="false">http://www.sergemeunier.com/blog/?p=1578</guid>
		<description><![CDATA[Another type of sharpening effect is mean removal. It works similarly to the standard sharpening, except it subtracts values from all the surrounding pixels evenly.
The grid which we used for this effect is as follows


-1
-1
-1


-1
11
-1


-1
-1
-1


This gives a much more noticeable sharpening effect on the image.
You can download the full code for the sample application which [...]


Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-sharpening-the-image/' rel='bookmark' title='Permanent Link: Image Processing in C#: Sharpening the image'>Image Processing in C#: Sharpening the image</a> <small>Sharpening an image is merely the inverse of what we...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-embossing/' rel='bookmark' title='Permanent Link: Image Processing in C#: Embossing'>Image Processing in C#: Embossing</a> <small>One of the most striking effects to apply to an...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-smoothing-using-convolution/' rel='bookmark' title='Permanent Link: Image Processing in C#: Smoothing using convolution'>Image Processing in C#: Smoothing using convolution</a> <small>Smoothing, which is just a type of blurring is based...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Another type of sharpening effect is mean removal. It works similarly to the <a href="http://www.sergemeunier.com/blog/image-processing-in-c-sharp-sharpening-the-image/">standard sharpening</a>, except it subtracts values from all the surrounding pixels evenly.</p>
<p>The grid which we used for this effect is as follows</p>
<table border='1'>
<tr>
<td>-1</td>
<td>-1</td>
<td>-1</td>
</tr>
<tr>
<td>-1</td>
<td>11</td>
<td>-1</td>
</tr>
<tr>
<td>-1</td>
<td>-1</td>
<td>-1</td>
</tr>
</table>
<p>This gives a much more noticeable sharpening effect on the image.</p>
<p><div id="attachment_1579" class="wp-caption aligncenter" style="width: 490px"><img src="http://www.sergemeunier.com/blog/wp-content/uploads/2010/01/Garfield-MeanRemoval.jpg" alt="Mean removal" title="Mean removal" width="480" height="180" class="size-full wp-image-1579" /><p class="wp-caption-text">Mean removal</p></div><br />
You can download the full code for the sample application which contains code for all the image effects covered in the series <a href="http://www.sergemeunier.com/downloads/ImageProcessor.zip">here</a>.</p>
<pre name="code" class="C-Sharp">
public void ApplyMeanRemoval(double weight)
{
    ConvolutionMatrix matrix = new ConvolutionMatrix(3);
    matrix.SetAll(1);
    matrix.Matrix[0, 0] = -1;
    matrix.Matrix[1, 0] = -1;
    matrix.Matrix[2, 0] = -1;
    matrix.Matrix[0, 1] = -1;
    matrix.Matrix[1, 1] = weight;
    matrix.Matrix[2, 1] = -1;
    matrix.Matrix[0, 2] = -1;
    matrix.Matrix[1, 2] = -1;
    matrix.Matrix[2, 2] = -1;
    matrix.Factor = weight - 8;
    bitmapImage = Convolution3x3(bitmapImage, matrix);

}
</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.sergemeunier.com%2Fblog%2Fimage-processing-in-c-sharp-applying-a-mean-removal%2F&amp;linkname=Image%20Processing%20in%20C%23%3A%20Applying%20a%20mean%20removal"><img src="http://www.sergemeunier.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-sharpening-the-image/' rel='bookmark' title='Permanent Link: Image Processing in C#: Sharpening the image'>Image Processing in C#: Sharpening the image</a> <small>Sharpening an image is merely the inverse of what we...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-embossing/' rel='bookmark' title='Permanent Link: Image Processing in C#: Embossing'>Image Processing in C#: Embossing</a> <small>One of the most striking effects to apply to an...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-smoothing-using-convolution/' rel='bookmark' title='Permanent Link: Image Processing in C#: Smoothing using convolution'>Image Processing in C#: Smoothing using convolution</a> <small>Smoothing, which is just a type of blurring is based...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-applying-a-mean-removal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Image Processing in C#: Sharpening the image</title>
		<link>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-sharpening-the-image/</link>
		<comments>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-sharpening-the-image/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 05:36:04 +0000</pubDate>
		<dc:creator>Serge Meunier</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Image processing]]></category>

		<guid isPermaLink="false">http://www.sergemeunier.com/blog/?p=1573</guid>
		<description><![CDATA[Sharpening an image is merely the inverse of what we did to blur the image. It also uses the convolution function, which you can read in my post about Smoothing using convolution.
Here we supply a convolution matrix set up as follows:


0
-2
0


-2
11
-2


0
-2
0


Here our weighting factor would total 3, since the negative numbers get subtracted from the [...]


Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-embossing/' rel='bookmark' title='Permanent Link: Image Processing in C#: Embossing'>Image Processing in C#: Embossing</a> <small>One of the most striking effects to apply to an...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-smoothing-using-convolution/' rel='bookmark' title='Permanent Link: Image Processing in C#: Smoothing using convolution'>Image Processing in C#: Smoothing using convolution</a> <small>Smoothing, which is just a type of blurring is based...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-applying-a-mean-removal/' rel='bookmark' title='Permanent Link: Image Processing in C#: Applying a mean removal'>Image Processing in C#: Applying a mean removal</a> <small>Another type of sharpening effect is mean removal. It works...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Sharpening an image is merely the inverse of what we did to blur the image. It also uses the convolution function, which you can read in my post about <a href="http://www.sergemeunier.com/blog/image-processing-in-c-sharp-smoothing-using-convolution/">Smoothing using convolution</a>.</p>
<p>Here we supply a convolution matrix set up as follows:</p>
<table border='1'>
<tr>
<td>0</td>
<td>-2</td>
<td>0</td>
</tr>
<tr>
<td>-2</td>
<td>11</td>
<td>-2</td>
</tr>
<tr>
<td>0</td>
<td>-2</td>
<td>0</td>
</tr>
</table>
<p>Here our weighting factor would total 3, since the negative numbers get subtracted from the weighting total. </p>
<p><div id="attachment_1574" class="wp-caption aligncenter" style="width: 490px"><img src="http://www.sergemeunier.com/blog/wp-content/uploads/2010/01/Garfield-Sharpen.jpg" alt="Shapening our image" title="Shapening our image" width="480" height="180" class="size-full wp-image-1574" /><p class="wp-caption-text">Shapening our image</p></div><br />
You can download the full code for the sample application which contains code for all the image effects covered in the series <a href="http://www.sergemeunier.com/downloads/ImageProcessor.zip">here</a>.</p>
<pre name="code" class="C-Sharp">
public void ApplySharpen(double weight)
{
    ConvolutionMatrix matrix = new ConvolutionMatrix(3);
    matrix.SetAll(1);
    matrix.Matrix[0, 0] = 0;
    matrix.Matrix[1, 0] = -2;
    matrix.Matrix[2, 0] = 0;
    matrix.Matrix[0, 1] = -2;
    matrix.Matrix[1, 1] = weight;
    matrix.Matrix[2, 1] = -2;
    matrix.Matrix[0, 2] = 0;
    matrix.Matrix[1, 2] = -2;
    matrix.Matrix[2, 2] = 0;
    matrix.Factor = weight - 8;
    bitmapImage = Convolution3x3(bitmapImage, matrix);

}
</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.sergemeunier.com%2Fblog%2Fimage-processing-in-c-sharp-sharpening-the-image%2F&amp;linkname=Image%20Processing%20in%20C%23%3A%20Sharpening%20the%20image"><img src="http://www.sergemeunier.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-embossing/' rel='bookmark' title='Permanent Link: Image Processing in C#: Embossing'>Image Processing in C#: Embossing</a> <small>One of the most striking effects to apply to an...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-smoothing-using-convolution/' rel='bookmark' title='Permanent Link: Image Processing in C#: Smoothing using convolution'>Image Processing in C#: Smoothing using convolution</a> <small>Smoothing, which is just a type of blurring is based...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-applying-a-mean-removal/' rel='bookmark' title='Permanent Link: Image Processing in C#: Applying a mean removal'>Image Processing in C#: Applying a mean removal</a> <small>Another type of sharpening effect is mean removal. It works...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-sharpening-the-image/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Image Processing in C#: Gaussian blur</title>
		<link>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-gaussian-blur/</link>
		<comments>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-gaussian-blur/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 05:39:57 +0000</pubDate>
		<dc:creator>Serge Meunier</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Image processing]]></category>

		<guid isPermaLink="false">http://www.sergemeunier.com/blog/?p=1565</guid>
		<description><![CDATA[Gaussian blur also uses convolution to create the effect. If you have not yet read my blog post on Smoothing using convolution, I would advise you to read that post first, as in that post I explain how the convolution function works.
Gaussian blur works very similarly to the smoothing function, in that both are a [...]


Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-sharpening-the-image/' rel='bookmark' title='Permanent Link: Image Processing in C#: Sharpening the image'>Image Processing in C#: Sharpening the image</a> <small>Sharpening an image is merely the inverse of what we...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-embossing/' rel='bookmark' title='Permanent Link: Image Processing in C#: Embossing'>Image Processing in C#: Embossing</a> <small>One of the most striking effects to apply to an...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-smoothing-using-convolution/' rel='bookmark' title='Permanent Link: Image Processing in C#: Smoothing using convolution'>Image Processing in C#: Smoothing using convolution</a> <small>Smoothing, which is just a type of blurring is based...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Gaussian blur also uses convolution to create the effect. If you have not yet read my blog post on <a href="http://www.sergemeunier.com/blog/image-processing-in-c-sharp-smoothing-using-convolution/">Smoothing using convolution</a>, I would advise you to read that post first, as in that post I explain how the convolution function works.</p>
<p>Gaussian blur works very similarly to the smoothing function, in that both are a type of blur, but the Gaussian blur gives a more natural looking blur. </p>
<p>It achieves this by not have a flat weighting, but instead has a weighting based on a Gaussian curve, thus for our 3&#215;3 grid, the values we want to supply the convolution function is as follows:</p>
<table border='1'>
<tr>
<td>1</td>
<td>2</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
<td>2</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>1</td>
</tr>
</table>
<p>The factor parameter is set to the sum of each pixel in the grid, which in this case, is again, 16, and the offset is set to 0.</p>
<p>Now we get a nice blur effect.<br />
<div id="attachment_1566" class="wp-caption aligncenter" style="width: 490px"><img src="http://www.sergemeunier.com/blog/wp-content/uploads/2010/01/Garfield-Guassian.jpg" alt="Applying a guassian blur" title="Applying a guassian blur" width="480" height="180" class="size-full wp-image-1566" /><p class="wp-caption-text">Applying a guassian blur</p></div><br />
You can download the full code for the sample application which contains code for all the image effects covered in the series <a href="http://www.sergemeunier.com/downloads/ImageProcessor.zip">here</a>.</p>
<pre name="code" class="C-Sharp">
public void ApplyGaussianBlur(double peakValue)
{
    ConvolutionMatrix matrix = new ConvolutionMatrix(3);
    matrix.SetAll(1);
    matrix.Matrix[0, 0] = peakValue / 4;
    matrix.Matrix[1, 0] = peakValue / 2;
    matrix.Matrix[2, 0] = peakValue / 4;
    matrix.Matrix[0, 1] = peakValue / 2;
    matrix.Matrix[1, 1] = peakValue;
    matrix.Matrix[2, 1] = peakValue / 2;
    matrix.Matrix[0, 2] = peakValue / 4;
    matrix.Matrix[1, 2] = peakValue / 2;
    matrix.Matrix[2, 2] = peakValue / 4;
    matrix.Factor = peakValue * 4;
    bitmapImage = Convolution3x3(bitmapImage, matrix);

}
</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.sergemeunier.com%2Fblog%2Fimage-processing-in-c-sharp-gaussian-blur%2F&amp;linkname=Image%20Processing%20in%20C%23%3A%20Gaussian%20blur"><img src="http://www.sergemeunier.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-sharpening-the-image/' rel='bookmark' title='Permanent Link: Image Processing in C#: Sharpening the image'>Image Processing in C#: Sharpening the image</a> <small>Sharpening an image is merely the inverse of what we...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-embossing/' rel='bookmark' title='Permanent Link: Image Processing in C#: Embossing'>Image Processing in C#: Embossing</a> <small>One of the most striking effects to apply to an...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-smoothing-using-convolution/' rel='bookmark' title='Permanent Link: Image Processing in C#: Smoothing using convolution'>Image Processing in C#: Smoothing using convolution</a> <small>Smoothing, which is just a type of blurring is based...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-gaussian-blur/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Image Processing in C#: Smoothing using convolution</title>
		<link>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-smoothing-using-convolution/</link>
		<comments>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-smoothing-using-convolution/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 05:30:30 +0000</pubDate>
		<dc:creator>Serge Meunier</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Image processing]]></category>

		<guid isPermaLink="false">http://www.sergemeunier.com/blog/?p=1559</guid>
		<description><![CDATA[Smoothing, which is just a type of blurring is based on a concept called convolution.
How this works is that you take a square section of pixels, often 3&#215;3 but can be any size, although the larger you make the grid, the less pixels that will get affected by the effect around the edges.
The centre pixel [...]


Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-embossing/' rel='bookmark' title='Permanent Link: Image Processing in C#: Embossing'>Image Processing in C#: Embossing</a> <small>One of the most striking effects to apply to an...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-sharpening-the-image/' rel='bookmark' title='Permanent Link: Image Processing in C#: Sharpening the image'>Image Processing in C#: Sharpening the image</a> <small>Sharpening an image is merely the inverse of what we...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-gaussian-blur/' rel='bookmark' title='Permanent Link: Image Processing in C#: Gaussian blur'>Image Processing in C#: Gaussian blur</a> <small>Gaussian blur also uses convolution to create the effect. If...</small></li>
</ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Smoothing, which is just a type of blurring is based on a concept called convolution.</p>
<p>How this works is that you take a square section of pixels, often 3&#215;3 but can be any size, although the larger you make the grid, the less pixels that will get affected by the effect around the edges.</p>
<p>The centre pixel of the grid is the main pixel we are interested in. To use convolution, what we do is assign weightings to each pixel in the grid, depending on what effect we are trying to achieve, and then assign the result to the centre pixel.</p>
<p>The basic data structure we use for the convolution is a class which contains the 2D array, as well as a weighting factor, and an offset.</p>
<pre name="code" class="C-Sharp">
    public class ConvolutionMatrix
    {
        public int MatrixSize = 3;

        public double[,] Matrix;
        public double Factor = 1;
        public double Offset = 1;

        public ConvolutionMatrix(int size)
        {
            MatrixSize = 3;
            Matrix = new double[size, size];
        }

        public void SetAll(double value)
        {
            for (int i = 0; i < MatrixSize; i++)
            {
                for (int j = 0; j < MatrixSize; j++)
                {
                    Matrix[i, j] = value;
                }
            }
        }
    }
</pre>
<p>Now, having this class, we can implement the convolution algorithm</p>
<pre name="code" class="C-Sharp">
public Bitmap Convolution3x3(Bitmap b, ConvolutionMatrix m)
{
    Bitmap newImg = (Bitmap)b.Clone();
    Color[,] pixelColor = new Color[3, 3];
    int A, R, G, B;

    for (int y = 0; y < b.Height - 2; y++)
    {
        for (int x = 0; x < b.Width - 2; x++)
        {
            pixelColor[0, 0] = b.GetPixel(x, y);
            pixelColor[0, 1] = b.GetPixel(x, y + 1);
            pixelColor[0, 2] = b.GetPixel(x, y + 2);
            pixelColor[1, 0] = b.GetPixel(x + 1, y);
            pixelColor[1, 1] = b.GetPixel(x + 1, y + 1);
            pixelColor[1, 2] = b.GetPixel(x + 1, y + 2);
            pixelColor[2, 0] = b.GetPixel(x + 2, y);
            pixelColor[2, 1] = b.GetPixel(x + 2, y + 1);
            pixelColor[2, 2] = b.GetPixel(x + 2, y + 2);

            A = pixelColor[1, 1].A;

            R = (int)((((pixelColor[0, 0].R * m.Matrix[0, 0]) +
                         (pixelColor[1, 0].R * m.Matrix[1, 0]) +
                         (pixelColor[2, 0].R * m.Matrix[2, 0]) +
                         (pixelColor[0, 1].R * m.Matrix[0, 1]) +
                         (pixelColor[1, 1].R * m.Matrix[1, 1]) +
                         (pixelColor[2, 1].R * m.Matrix[2, 1]) +
                         (pixelColor[0, 2].R * m.Matrix[0, 2]) +
                         (pixelColor[1, 2].R * m.Matrix[1, 2]) +
                         (pixelColor[2, 2].R * m.Matrix[2, 2]))
                                / m.Factor) + m.Offset);

            if (R < 0)
            {
                R = 0;
            }
            else if (R > 255)
            {
                R = 255;
            }

            G = (int)((((pixelColor[0, 0].G * m.Matrix[0, 0]) +
                         (pixelColor[1, 0].G * m.Matrix[1, 0]) +
                         (pixelColor[2, 0].G * m.Matrix[2, 0]) +
                         (pixelColor[0, 1].G * m.Matrix[0, 1]) +
                         (pixelColor[1, 1].G * m.Matrix[1, 1]) +
                         (pixelColor[2, 1].G * m.Matrix[2, 1]) +
                         (pixelColor[0, 2].G * m.Matrix[0, 2]) +
                         (pixelColor[1, 2].G * m.Matrix[1, 2]) +
                         (pixelColor[2, 2].G * m.Matrix[2, 2]))
                                / m.Factor) + m.Offset);

            if (G < 0)
            {
                G = 0;
            }
            else if (G > 255)
            {
                G = 255;
            }

            B = (int)((((pixelColor[0, 0].B * m.Matrix[0, 0]) +
                         (pixelColor[1, 0].B * m.Matrix[1, 0]) +
                         (pixelColor[2, 0].B * m.Matrix[2, 0]) +
                         (pixelColor[0, 1].B * m.Matrix[0, 1]) +
                         (pixelColor[1, 1].B * m.Matrix[1, 1]) +
                         (pixelColor[2, 1].B * m.Matrix[2, 1]) +
                         (pixelColor[0, 2].B * m.Matrix[0, 2]) +
                         (pixelColor[1, 2].B * m.Matrix[1, 2]) +
                         (pixelColor[2, 2].B * m.Matrix[2, 2]))
                                / m.Factor) + m.Offset);

            if (B < 0)
            {
                B = 0;
            }
            else if (B > 255)
            {
                B = 255;
            }
            newImg.SetPixel(x+1, y+1, Color.FromArgb(A, R, G, B));
        }
    }
    return newImg;
}
</pre>
<p>Finally, after all that, we are ready to implement a smoothing function. To smooth an image, we assign a particular value to the centre pixel, and then 1 to all the surrounding pixels, so the array would look something like this</p>
<table border='1'>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>8</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
</table>
<p>The factor parameter is set to the sum of each pixel in the grid, which in this case would be 16, and the offset is set to 0. The offset shifts all the values of the colour components by the specified amount.</p>
<p>Now all that is left is calling the convolution function.<br />
<div id="attachment_1560" class="wp-caption aligncenter" style="width: 490px"><img src="http://www.sergemeunier.com/blog/wp-content/uploads/2010/01/Garfield-Smooth.jpg" alt="Smoothing" title="Smoothing" width="480" height="180" class="size-full wp-image-1560" /><p class="wp-caption-text">Smoothing</p></div><br />
You can download the full code for the sample application which contains code for all the image effects covered in the series <a href="http://www.sergemeunier.com/downloads/ImageProcessor.zip">here</a>.</p>
<pre name="code" class="C-Sharp">
        public void ApplySmooth(double weight)
        {
            ConvolutionMatrix matrix = new ConvolutionMatrix(3);
            matrix.SetAll(1);
            matrix.Matrix[1,1] = weight;
            matrix.Factor = weight + 8;
            bitmapImage = Convolution3x3(bitmapImage, matrix);

        }
</pre>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.sergemeunier.com%2Fblog%2Fimage-processing-in-c-sharp-smoothing-using-convolution%2F&amp;linkname=Image%20Processing%20in%20C%23%3A%20Smoothing%20using%20convolution"><img src="http://www.sergemeunier.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-embossing/' rel='bookmark' title='Permanent Link: Image Processing in C#: Embossing'>Image Processing in C#: Embossing</a> <small>One of the most striking effects to apply to an...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-sharpening-the-image/' rel='bookmark' title='Permanent Link: Image Processing in C#: Sharpening the image'>Image Processing in C#: Sharpening the image</a> <small>Sharpening an image is merely the inverse of what we...</small></li>
<li><a href='http://www.sergemeunier.com/blog/image-processing-in-c-sharp-gaussian-blur/' rel='bookmark' title='Permanent Link: Image Processing in C#: Gaussian blur'>Image Processing in C#: Gaussian blur</a> <small>Gaussian blur also uses convolution to create the effect. If...</small></li>
</ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sergemeunier.com/blog/image-processing-in-c-sharp-smoothing-using-convolution/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
