<?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>geeks have feelings</title>
	<atom:link href="http://www.geekshavefeelings.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.geekshavefeelings.com</link>
	<description>xo wang</description>
	<lastBuildDate>Tue, 27 Jul 2010 04:54:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>C++’s .* and -&gt;* operators: Part 3</title>
		<link>http://www.geekshavefeelings.com/posts/cs-and-operators-part-3</link>
		<comments>http://www.geekshavefeelings.com/posts/cs-and-operators-part-3#comments</comments>
		<pubDate>Tue, 27 Jul 2010 03:40:50 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[comp.sci]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=715</guid>
		<description><![CDATA[Well, none of my drafts are yet worth putting up (preview: the first part of a long series on color theory, and a follow-up to the academic advising drama &#8220;I Am Now a Management Major&#8220;), so here&#8217;s another filler post. Welcome back, and thanks for picking up this April Fools&#8217; issue of “@#$%ing Strange C++: [...]]]></description>
			<content:encoded><![CDATA[<p><em>Well, none of my drafts are yet worth putting up (preview: the first part of a long series on color theory, and a follow-up to the academic advising drama &#8220;<a title="I Am Now a Management Major" href="http://www.geekshavefeelings.com/posts/i-am-now-a-management-major">I Am Now a Management Major</a>&#8220;), so here&#8217;s another filler post.</em></p>
<p>Welcome back, and thanks for picking up this April Fools&#8217; issue of “@#$%ing Strange C++: I hate this language <em>sooo</em> much.” Today, let&#8217;s take our example code from last time and apply some textbook techniques to screw it u—improve its readability and reusability.</p>
<p>Why would anyone do this with example code written to show an entirely awful concept with an entirely contrived example? I don&#8217;t know.</p>
<p>Let&#8217;s backpedal to the important part: <code>Vector3D</code>. Hey, we named it <code>Vector3D</code>, so why does it only allow <code>float</code>s? Why doesn&#8217;t it do any vector-y stuff? LET US ADD SOME FUNCTIONALITY WHICH WE WILL NOT USE.</p>
<pre class="brush: cpp; highlight: [2,5,12]; light: true;">// HELL YEAH, LET'S TEMPLATE IT
template&lt;typename Component_T = double&gt; // STICK IN A DEFAULT, EVEN IF IT DOESN'T MAKE SENSE
class Vector3D {
public:
	typedef Component_T ComponentType; // YOU'LL SEE WHY WE NEED THIS

	Component_T x;
	Component_T y;
	Component_T z;

	// Component_T MIGHT BE A BIGNUM CLASS OR SOMETHING, SO WE PASS CONST REFERENCES
	Vector3D(const Component_T &amp;x, const Component_T &amp;y, const Component_T &amp;z) :
		x(x), y(y), z(z) {
	}</pre>
<p>Mmm-hmm, templates are a sure part of any messy C++ recipe. Once you learn them, you&#8217;ll never remember how to program well again. Let&#8217;s continue on to the operator overloads. We completely ignore the fact that infix notation makes no sense in a language that features prefix for <em>everything</em> else, or that these are all really constructors, so they&#8217;re better off as constructors in the <a href="http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.8">&#8220;named constructors&#8221; idiom</a>, or that nobody ever follows the same conventions for these &#8220;arithmetic&#8221; operators; we&#8217;re using them because they&#8217;re snazzy little bits of sugar coating.</p>
<pre class="brush: cpp; light: true;">	// OPERATOR OVERLOADS ALL OVER THE PLACE
	friend Vector3D operator-(const Vector3D &amp;a) {
		return Vector3D(-a.x, -a.y, -a.z);
	}

	friend Vector3D operator+(const Vector3D &amp;a, const Vector3D &amp;b) {
		return Vector3D(a.x + b.x, a.y + b.y, a.z + b.z);
	}

	friend Vector3D operator-(const Vector3D &amp;a, const Vector3D &amp;b) {
		return Vector3D(a.x - b.x, a.y - b.y, a.z - b.z);
	}

	// WE DON'T CARE THAT SOMETIMES PEOPLE WANT THE INNER (DOT) PRODUCT
	friend Vector3D operator*(const Vector3D &amp;a, const Vector3D &amp;b) {
		return Vector3D(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
	}

	friend Vector3D operator*(const Vector3D &amp;a, const Component_T &amp;s) {
		return Vector3D(a.x * s, a.y * s, a.z * s);
	}

	// LOLOL REDUNDANT
	friend Vector3D operator*(const Component_T &amp;s, const Vector3D &amp;a) {
		return Vector3D(a.x * s, a.y * s, a.z * s);
	}

	friend Vector3D operator/(const Vector3D &amp;a, const Component_T &amp;s) {
		return Vector3D(a.x / s, a.y / s, a.z / s);
	}

	// BECAUSE a.dot(b) IS LIKE THE OTHER OPERATORS, NOT BECAUSE INFIX IS GOOD
	Vector3D dot(const Vector3D &amp;a) {
		return Vector3D(x * a.x, y * a.y, z * a.z);
	}

	friend std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, const Vector3D &amp;v) {
		return os &lt;&lt; '&lt;' &lt;&lt; v.x &lt;&lt; &quot;, &quot; &lt;&lt; v.y &lt;&lt; &quot;, &quot; &lt;&lt; v.z &lt;&lt; '&gt;';
	}
};</pre>
<p>Alright, now that we have blinged out <code>Vector3D</code> for no apparent reason, let&#8217;s extend our <code>Operation</code> cla—oh crud, there&#8217;s unqualified types needing the <code>typename</code> keyword, template parameters, and angled brackets <em>all over the place</em>. What to do? We&#8217;ll <code>typedef</code> everything away, of course.</p>
<pre class="brush: cpp; highlight: [1,2,5,7,8]; light: true;">template&lt;typename Vector3D_T&gt; // DAMN, NOW WE HAVE TO TEMPLATE THIS
class Operation: public std::binary_function&lt;Vector3D_T, typename Vector3D_T::ComponentType, void&gt; {
protected:
	// WE NEED typename TO FULLY QUALIFY; DON'T ASK WHY
	typedef typename Vector3D_T::ComponentType ComponentType;
	// (ROYAL) WE DON'T FEEL LIKE TYPING THESE ANY MORE
	typedef void (Operation::*OperationPointerType)(Vector3D_T &amp;, const ComponentType &amp;) const;
	typedef ComponentType Vector3D_T::*ComponentPointerType;

	// a pointer to a const member function with params (Vector3D &amp;, float) returning void
	OperationPointerType operationPtr;
	// store the component selection using a member pointer
	ComponentPointerType componentPtr;</pre>
<p>Just for the hell of it, let&#8217;s derive from <code>std::binary_function</code> to pollute our class namespace and let us do weird, fancy things with argument binding in <code>&lt;functional&gt;</code> and algorithms from <code>&lt;algorithm&gt;</code>, <code>&lt;numeric&gt;</code>, etc.</p>
<pre class="brush: cpp; light: true;">public:
	Operation(OperationPointerType const operationPtr, ComponentPointerType const componentPtr) :
		operationPtr(operationPtr), componentPtr(componentPtr) {
	}

	void setComponent(ComponentPointerType const componentPtr) {
		this-&gt;componentPtr = componentPtr;
	}

	void setOperation(OperationPointerType const operation) {
		this-&gt;operationPtr = operation;
	}</pre>
<p>I guess it&#8217;s a little better with the <code>typedef</code>s. But here we go with the <code>operator()</code> overload that makes this a proper <code>std::binary_function</code>:</p>
<pre class="brush: cpp; light: true;">	// HELL YEAH, LET'S MAKE THIS A FUNCTOR
	void operator()(Vector3D_T &amp;vector3D, const ComponentType &amp;x) const {
		(this-&gt;*operationPtr)(vector3D, x);
	}

	void add(Vector3D_T &amp;vector3D, const ComponentType &amp;x) const {
		vector3D.*componentPtr += x;
	}

	void sub(Vector3D_T &amp;vector3D, const ComponentType &amp;x) const {
		vector3D.*componentPtr -= x;
	}
};</pre>
<p>Wait a minute. This almost the same thing as from the article, just all weird looking. Feeling duped? You should be. Templating will make you feel all empty inside like that. But let&#8217;s see what we can do with this now:</p>
<pre class="brush: cpp; highlight: [3]; light: true;">int main() {
	std::vector&lt;Vector3D&lt;float&gt; &gt; vs(5, Vector3D&lt;float&gt; (0, 2, 3)); // create five &lt;0, 2, 3&gt;s
	std::copy(vs.begin(), vs.end(), std::ostream_iterator&lt;Vector3D&lt;float&gt; &gt;(std::cout, &quot; &quot;));
	std::cout &lt;&lt; std::endl; // print out the list</pre>
<p>In case you haven&#8217;t noticed yet, that&#8217;s working code for writing stuff to a stream; you can actually get an output iterator from a <code>std::ostream</code> and copy into it as with any other iterator.</p>
<pre class="brush: cpp; highlight: [2]; light: true;">std::cout &lt;&lt; &quot;Negating vectors...&quot; &lt;&lt; std::endl;
	std::transform(vs.begin(), vs.end(), vs.begin(), std::negate&lt;Vector3D&lt;float&gt; &gt;());
	std::copy(vs.begin(), vs.end(), std::ostream_iterator&lt;Vector3D&lt;float&gt; &gt;(std::cout, &quot; &quot;));
	std::cout &lt;&lt; std::endl; // print out the list</pre>
<p>WHOA MAN, THAT&#8217;S A FANCY NEGATE. <code>std::negate</code> creates a class fitting the unary_operator concept, which is a functor of arity one. Specifically, it uses the templated class&#8217;s <code>operator-</code> in the functor to return the negative of whatever is passed to the functor.</p>
<p>More fanciness:</p>
<pre class="brush: cpp; highlight: [3,10]; light: true;">	Operation&lt;Vector3D&lt;float&gt; &gt; vectorOp(&amp;Operation&lt;Vector3D&lt;float&gt; &gt;::add, &amp;Vector3D&lt;float&gt;::z);
	std::cout &lt;&lt; &quot;Adding to component z...&quot; &lt;&lt; std::endl;
	std::for_each(vs.begin(), vs.end(), std::bind2nd(vectorOp, 1.f));
	std::copy(vs.begin(), vs.end(), std::ostream_iterator&lt;Vector3D&lt;float&gt; &gt;(std::cout, &quot; &quot;));
	std::cout &lt;&lt; std::endl; // print out the list again

	vectorOp.setOperation(&amp;Operation&lt;Vector3D&lt;float&gt; &gt;::sub); // note the use of &amp; operator
	vectorOp.setComponent(&amp;Vector3D&lt;float&gt;::y);
	std::cout &lt;&lt; &quot;Subtracting from component y...&quot; &lt;&lt; std::endl;
	std::for_each(vs.begin(), vs.end(), std::bind2nd(vectorOp, 3.f));
	std::copy(vs.begin(), vs.end(), std::ostream_iterator&lt;Vector3D&lt;float&gt; &gt;(std::cout, &quot; &quot;));
	std::cout &lt;&lt; std::endl; // print out the list again

	return EXIT_SUCCESS;
}</pre>
<p>Yes, there I am actually &#8220;binding&#8221; a fixed value to the second parameter of my functor, something which required the use of <code>std::binary_function</code> to work. There is a better alternative that doesn&#8217;t require this, nor restrict us to binary (arity-two) functors, nor require us to specify the parameter to bind in such a cumbersome way. It&#8217;s called <code>boost::bind</code>, and you&#8217;re not going to use it because you&#8217;ll discover that <code>boost::lambda</code> is better in every regard, and that you&#8217;ll be turned off by having to stick Boost&#8217;s bulk into code you found on a blog.</p>
<p>Next steps? Well, we should document the hell out of this. Mmm, yeah, let&#8217;s bring in some Doxygen, or even better, some lightweight boutique documentation generator! Let&#8217;s write some embedded documenta&#8230; eh, we&#8217;re too lazy.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/cs-and-operators-part-3/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C++’s .* and -&gt;* operators: Part 2</title>
		<link>http://www.geekshavefeelings.com/posts/cs-and-operators-part-2</link>
		<comments>http://www.geekshavefeelings.com/posts/cs-and-operators-part-2#comments</comments>
		<pubDate>Thu, 10 Jun 2010 00:14:31 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[comp.sci]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=686</guid>
		<description><![CDATA[Welcome back to &#8220;Strange C++.&#8221; Today we will continue the exploration of C++&#8217;s pointer-to-member features, begun in Part 1 of this series, by using the .* and -&#62;* operators to access pointers to member functions—that is, methods. Last time in Part 1 we looked at how member pointers helped us to &#8220;cache&#8221; the choice of [...]]]></description>
			<content:encoded><![CDATA[<p>Welcome back to &#8220;Strange C++.&#8221; Today we will continue the exploration of C++&#8217;s pointer-to-member features, begun in <a href="http://www.geekshavefeelings.com/posts/cs-and-operators-part-1">Part 1 of this series</a>, by using the <code>.*</code> and <code>-&gt;*</code> operators to access pointers to member functions—that is, methods.</p>
<p><a href="http://www.geekshavefeelings.com/posts/cs-and-operators-part-1">Last time in Part 1</a> we looked at how member pointers helped us to &#8220;cache&#8221; the choice of a float member in a hypothetical 3D vector class, <code>Vector3D</code>. Then we used this member pointer storing the choice of component to add a float to an arbitrary component of a <code>std::vector</code> of <code>Vector3D</code>s.</p>
<p>Now our goal for this article is to extend our code acting on vectors: instead of just <em>adding</em> to an arbitrary component of <code>Vector3D</code>, we&#8217;d like to perform an <em>arbitrary operation</em> instead. This means that along with the selection of component, we&#8217;d like to also store a selection of operation to perform on that component. Then we&#8217;d like to apply that operation to a <code>Vector3D</code> without needing expensive<sup>1</sup> conditionals or switch statements.</p>
<p>So let&#8217;s sketch up some code. Here&#8217;s a quick class that represents an arbitrary operation on a <code>Vector3D</code>, which stores which component to operate on:</p>
<pre class="brush: cpp; light: true;">// Represents an operation done against one component of a Vector3D
class Operation {
protected:
	float Vector3D::*componentPtr; // store the component selection using a member pointer

public:
	Operation(float Vector3D::* const componentPtr) :
		componentPtr(componentPtr) {
	}

	void setComponent(float Vector3D::* const componentPtr) {
		this-&gt;componentPtr = componentPtr;
	}

	virtual void op(Vector3D &amp;vector3D, float f) const = 0; // interface to use the operation
};</pre>
<p>Given the requirements and what we know about member pointers from the last article, this seems like a reasonable way to store the &#8220;arbitrary component&#8221; selection in a class. To realize the &#8220;arbitrary operations&#8221; part of the deal, you&#8217;d have to derive from this class into the actual operations, in a textbook example of polymorphism:</p>
<pre class="brush: cpp; highlight: [8,19]; light: true;">class OperationAdd : public Operation {
public:
	OperationAdd(float Vector3D::* const componentPtr) :
		Operation(componentPtr) {
	}

	void op(Vector3D &amp;vector3D, float f) const {
		vector3D.*componentPtr += f; // specialize the operation as addition
	}
};

class OperationSub : public Operation {
public:
	OperationSub(float Vector3D::* const componentPtr) :
		Operation(componentPtr) {
	}

	void op(Vector3D &amp;vector3D, float f) const {
		vector3D.*componentPtr -= f; // specialize the operation as subtraction
	}
};</pre>
<p>Now, using polymorphism is a perfectly natural way to solve the problem for a C++ programmer. Just implement the interface by overriding <code>op()</code> and passing the component member pointer to the parent constructor: easy. Note the use of <code>Operation::componentPtr</code> to access the &#8220;cached&#8221; component selection. This might be how you&#8217;d want to use these classes:</p>
<pre class="brush: cpp; light: true;">void applyOperation(std::vector&lt;Vector3D&gt; &amp;vs, const Operation &amp;operation, float amount) {
	for(std::vector&lt;Vector3D&gt;::iterator v_i = vs.begin() ; v_i != vs.end() ; v_i++) {
		operation.op(*v_i, amount); // apply the operation to every Vector3D
	}
}

int main() {
	std::vector&lt;Vector3D&gt; vs(5, Vector3D(0, 2, 3)); // create five &lt;0, 2, 3&gt;s
	std::copy(vs.begin(), vs.end(), std::ostream_iterator&lt;Vector3D&gt;(std::cout, &quot; &quot;));
	std::cout &lt;&lt; std::endl; // print out the list

	OperationAdd vectorAdd(&amp;Vector3D::z); // create an &quot;addition to .z&quot; operation
	std::cout &lt;&lt; &quot;Adding to component z...&quot; &lt;&lt; std::endl;
	applyOperation(vs, vectorAdd, 1.f); // apply &quot;addition of 1 to .z&quot; to all vectors
	std::copy(vs.begin(), vs.end(), std::ostream_iterator&lt;Vector3D&gt;(std::cout, &quot; &quot;));
	std::cout &lt;&lt; std::endl; // print out the list again

	OperationSub vectorSub(&amp;Vector3D::y); // create an &quot;subtraction from .y&quot; operation
	std::cout &lt;&lt; &quot;Subtracting from component y...&quot; &lt;&lt; std::endl;
	applyOperation(vs, vectorSub, 3.f); // apply &quot;subtraction of 3 from .y&quot; to all vectors
	std::copy(vs.begin(), vs.end(), std::ostream_iterator&lt;Vector3D&gt;(std::cout, &quot; &quot;));
	std::cout &lt;&lt; std::endl; // print out the list again

	return EXIT_SUCCESS;
}</pre>
<p>Example output:</p>
<pre>&lt;0, 2, 3&gt; &lt;0, 2, 3&gt; &lt;0, 2, 3&gt; &lt;0, 2, 3&gt; &lt;0, 2, 3&gt;
Adding to component z...
&lt;0, 2, 4&gt; &lt;0, 2, 4&gt; &lt;0, 2, 4&gt; &lt;0, 2, 4&gt; &lt;0, 2, 4&gt;
Subtracting from component y...
&lt;0, -1, 4&gt; &lt;0, -1, 4&gt; &lt;0, -1, 4&gt; &lt;0, -1, 4&gt; &lt;0, -1, 4&gt;</pre>
<p>But there&#8217;s a lot of code duplication for the <code>OperationAdd</code> and <code>OperationSub</code> classes, isn&#8217;t there? You have to write a heck of a lot of code to account for what is essentially one character of difference between each operation.</p>
<p>In addition, as a design decision, shouldn&#8217;t selecting &#8220;which component&#8221; be similar to selecting &#8220;which operation?&#8221; Why does the latter require instantiating a new object of another subclass of <code>Operation</code>, yet the former requires only a call to <code>Operation::setComponent</code>?</p>
<p>To amend this, I&#8217;d like to introduce the member function pointer. It is exactly what it sounds like: a pointer to a member function, also known as &#8220;method.&#8221; A member function pointer can point to any method that has the same parameter list, return type, and const-ness as specified in the pointer&#8217;s type. Let&#8217;s see an example:</p>
<pre class="brush: cpp; light: true;">class Example {
public:
	void printA() {
		std::cout &lt;&lt; 'A' &lt;&lt; std::endl;
	}

	void printB() {
		std::cout &lt;&lt; 'B' &lt;&lt; std::endl;
	}

	static void printC();
};

void Example::printC() {
	std::cout &lt;&lt; 'C' &lt;&lt; std::endl;
}

void printD() {
	std::cout &lt;&lt; 'D' &lt;&lt; std::endl;
}

int main() {
	// member function pointers:
	Example example;
	void (Example::*printMethod)() = &amp;Example::printA; // declare a pointer to printA
	(example.*printMethod)(); // prints 'A'
	printMethod = &amp;Example::printB; // reassign pointer to printB
	(example.*printMethod)(); // prints 'B'

	// regular function pointers:
	// even though printC is part of Example, a regular function will do
	void (*printFunc)() = Example::printC; // see how the &quot;&amp;&quot; isn't needed
	printFunc(); // prints C
	printFunc = printD; // here too, &quot;&amp;&quot; is omitted
	printFunc(); // prints D
}</pre>
<p>I think it&#8217;s pretty self-explanatory, but let&#8217;s go through it anyways. <code>void (Example::*printMethod)()</code> is the declaration of the &#8220;<code>printMethod</code>&#8221; pointer variable. This syntax should be ringing bells in your head if you know member pointer syntax and function pointer syntax. Note, however, that we can&#8217;t use just &#8220;<code>Example::printA</code>&#8221; to initialize the pointer; we need to use the address-of operator (<code>&amp;</code>) as well. I&#8217;m not entirely sure why there is such a discrepancy between the syntaxes used for normal function and member functions. The fact that the parameter list has greater precedence than the <code>.*</code> and <code>-&gt;*</code> operators leads to another unfortunate syntax: parentheses around the class instance, <code>.*</code> or <code>-&gt;*</code>, and the member function pointer.</p>
<p>Now let&#8217;s try putting member function pointers to use in our <code>Vector3D</code> example. It&#8217;s really as simple as changing <code>Operation</code> to explicitly store the selected operation member function, rather than implicitly in the case of polymorphism (more on this later):</p>
<pre class="brush: cpp; highlight: [22]; light: true;">class Operation {
protected:
	// a pointer to a const member function with params (Vector3D &amp;, float) returning void
	void (Operation::*operationPtr)(Vector3D &amp;, float) const;
	// store the component selection using a member pointer
	float Vector3D::*componentPtr;

public:
	Operation(void(Operation::*operationPtr)(Vector3D &amp;, float) const, float Vector3D::* const componentPtr) :
		operationPtr(operationPtr), componentPtr(componentPtr) {
	}

	void setComponent(float Vector3D::* const componentPtr) {
		this-&gt;componentPtr = componentPtr;
	}

	void setOperation(void(Operation::* const operation)(Vector3D &amp;, float) const) {
		this-&gt;operationPtr = operation;
	}

	void op(Vector3D &amp;vector3D, float f) const {
		(this-&gt;*operationPtr)(vector3D, f); // call the member (add or sub)
	}

	void add(Vector3D &amp;vector3D, float f) const {
		vector3D.*componentPtr += f;
	}

	void sub(Vector3D &amp;vector3D, float f) const {
		vector3D.*componentPtr -= f;
	}
};</pre>
<p>All we&#8217;ve done here is add the two example operations (addition and subtraction) as methods of <code>Operation</code>, as well as a new member, <code>operationPtr</code>, which points to either <code>add</code> or <code>sub</code><sup>2</sup>. We&#8217;ve kept the <code>op()</code> interface the same, so the other difference is how we construct the <code>Operation</code> instance and how to change the operation selection:</p>
<pre class="brush: cpp; highlight: [4,5]; light: true;">Operation vectorOp(&amp;Operation::add, &amp;Vector3D::z); // create an &quot;addition to .z&quot; operation
applyOperation(vs, vectorOp, 1.f); // apply &quot;addition of 1 to .z&quot; to all vectors

vectorOp.setOperation(&amp;Operation::sub); // note the use of &amp; operator
vectorOp.setComponent(&amp;Vector3D::y);
applyOperation(vs, vectorOp, 3.f); // apply &quot;subtraction of 3 from .y&quot; to all vectors</pre>
<p>Note how the lines of <code>vectorOp.setOperation(&amp;Operation::sub)</code> and <code>vectorOp.setComponent(&amp;Vector3D::y)</code> look so&#8230; symmetrical. We can now move independently in the space of operations from the space of <code>Vector3D</code> components. This is known as <em>orthogonality</em>, which is just a fancy way of saying that this code feels nice to use.</p>
<p>Now about the technicals: if you understand the mechanism behind polymorphism, you&#8217;ll recognize that this solution is very similar to said mechanism. In fact, it&#8217;s likely more efficient. A virtual function call requires dereferencing the VPTR, looking up the appropriate member function from VTABLE (which you&#8217;ll now recognize is simply an array of member function pointers), and calling the pointer retrieved. This solution skips straight to calling the member function pointer—an elegant way to strip away unnecessary functionality and code duplication.</p>
<p>So there you have it, folks. I started writing these two articles when I looked online at the explanations for how to use member pointers and noticed that every single one of them showed completely pointless examples. They all seemed to describe pointers to members and member functions as an oddity, a silly way to rename a class&#8217;s contents.</p>
<p>Hopefully I&#8217;ve proven them otherwise and you now have an idea of how to utilize these little guys to construct cleaner, faster code.</p>
<p><em>Stay tuned for more “Strange C++.” Maybe. Actually, don&#8217;t count on it.</em></p>
<p><em>You should read &#8220;<a href="http://www.geekshavefeelings.com/posts/cs-and-operators-part-1">C++&#8217;s .* and -&gt;* operators: Part 1</a></em><em><em>&#8221; if you haven&#8217;t already.</em></em></p>
<ol class="footnotes"><li id="footnote_0_686" class="footnote">&#8220;Expensive&#8221; meaning conditionals can cause additional per-element overhead when batch processing due to branch misprediction and the subsequent pipeline eviction, in superscalar pipelined architectures.</li><li id="footnote_1_686" class="footnote">Actually, it can point to <code>op</code> as well, which would cause an infinite recursive loop. Oops.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/cs-and-operators-part-2/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C++&#8217;s .* and -&gt;* operators: Part 1</title>
		<link>http://www.geekshavefeelings.com/posts/cs-and-operators-part-1</link>
		<comments>http://www.geekshavefeelings.com/posts/cs-and-operators-part-1#comments</comments>
		<pubDate>Sat, 15 May 2010 23:19:29 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[comp.sci]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=633</guid>
		<description><![CDATA[Welcome to the newest installment of &#8220;Strange C++.&#8221; Today we&#8217;ll be discussing the .* and -&#62;* operators in C++. If you&#8217;re like me, then you probably spend all of your free time reading C++ FAQ Lite for some reason. Of course I don&#8217;t do that, because that&#8217;d be kind of weird and antisocial, but I [...]]]></description>
			<content:encoded><![CDATA[<p>Welcome to the newest installment of &#8220;Strange C++.&#8221; Today we&#8217;ll be discussing the <code>.*</code> and <code>-&gt;*</code> operators in C++.</p>
<p>If you&#8217;re like me, then you probably spend all of your free time reading <a title="C++ FAQ Lite" href="http://www.parashift.com/c++-faq-lite/">C++ FAQ Lite</a> for some reason. Of course I don&#8217;t do that, because that&#8217;d be kind of weird and antisocial, but I figure people like me are probably weird and antisocial. It&#8217;s a self-deprecatory safeguard for the sake of modesty.</p>
<p>At any rate, you&#8217;d have come across the rules for which C++ operators can and can&#8217;t be overloaded. Those in the &#8220;can&#8217;t&#8221; camp are the ternary operator <code>?:</code>, the scope spec operator <code>::</code>, the member-of operator <code>.</code>, and finally the <code>.*</code> operator<sup>1</sup>. What the Bjarne Stroustrup is that?</p>
<p>In few words, the <code>.*</code> operator accesses an object&#8217;s member pointed to by a member pointer. The <code>-&gt;*</code> pointer does the same thing, only it accesses the member of a pointer to an object, not an object or its reference. Unfortunately, this does nothing to clarify the operator&#8217;s use and introduces the additional question: what is a member pointer? This is the heart of the article, and I will explain through examples.</p>
<p>Let&#8217;s say we had the following class, representing a vector in R<sup>3</sup>:</p>
<pre class="brush: cpp; light: true;">class Vector3D {
public:
	float x;
	float y;
	float z;

	Vector3D(float x, float y, float z) :
		x(x), y(y), z(z) {
	}

	friend std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, const Vector3D &amp;v) {
		return os &lt;&lt; '&lt;' &lt;&lt; v.x &lt;&lt; &quot;, &quot; &lt;&lt; v.y &lt;&lt; &quot;, &quot; &lt;&lt; v.z &lt;&lt; '&gt;';
	}
};</pre>
<p>This is how you could use member pointers, taking note of the use of the <code>.*</code> operator:</p>
<pre class="brush: cpp; highlight: [5,6,9,10]; light: true;">int main() {
	Vector3D v(0, 2, 3);
	std::cout &lt;&lt; v &lt;&lt; std::endl; // output: &lt;0, 2, 3&gt;

	float Vector3D::*componentPtr = &amp;Vector3D::x; // member pointer to the x member
	v.*componentPtr += 1.f; // &quot;dereference&quot; it against instance v and add 1.f to it
	std::cout &lt;&lt; v &lt;&lt; std::endl; // output: &lt;1, 2, 3&gt;

	componentPtr = &amp;Vector3D::y; // now point it to the y member
	v.*componentPtr *= 2.f; // &quot;dereference&quot; it against instance v and mul it by 2.f
	std::cout &lt;&lt; v &lt;&lt; std::endl; // output: &lt;1, 4, 3&gt;

	return EXIT_SUCCESS;
}</pre>
<p>Now you might say: &#8220;Well, that looks like a whole lot of gibberish symbols to me. What does it mean and what does it do?&#8221;</p>
<p>Well, first we&#8217;re declaring and initializing a variable called <code>componentPtr</code>. What <code>componentPtr</code> does is point to a member of <code>Vector3D</code> of the type float. Take a cue from its declaration syntax: note that the asterisk, indicating a pointer (or indirection), comes after &#8220;<code>Vector3D::</code>&#8221; in &#8220;<code>float Vector3D::*componentPtr</code>.&#8221; Take this to mean that it&#8217;s a pointer that can move <em>within the space of the <code>Vector3D::</code> scope</em>.</p>
<p>Also take another clue from the initialization: it&#8217;s initialized to <code>&amp;Vector3D::x</code>—the address of the x member in <em>any</em> <code>Vector3D</code> instance, not say, <code>&amp;v.x</code>. So, when we use the pointer later, we need to specify <em>which</em> <code>Vector3D</code> instance it goes with: <code>v.*componentPtr</code></p>
<p><strong>Aside</strong><br />
I think of member pointers as offsets from the &#8220;<code>this</code>&#8221; pointers of instances. Imagine each instance as an instance of a packed POD (Plain Ol&#8217;Data) structure that contains two 32-bit floats, x then y, and a pointer to the structure points to its beginning. So, <code>v.y</code> would be the same thing as <code>*reinterpret_cast&lt;float *&gt;(reinterpret_cast&lt;uintptr_t&gt;(&amp;v) + sizeof(float))</code> and <code>v.x</code> would be <code>*reinterpret_cast&lt;float *&gt;(&amp;v)</code>. Indeed, that expression will work on most compilers (though you obviously shouldn&#8217;t use it).</p>
<p>Thus, I imagine <code>componentPtr</code> to be the &#8220;<code>+ sizeof(float)</code>&#8221; constant offset that marks how to use the object&#8217;s address to access the desired member. If you didn&#8217;t get any of the last two paragraphs, just pretend you didn&#8217;t read them, because it&#8217;s not too important.<br />
<strong>End aside</strong></p>
<p>So now you see how to use member pointers and how they work. But you&#8217;re probably thinking, &#8220;Xo, what the heck would compel any sane C++ programmer to use member pointers? In your last example, why couldn&#8217;t someone just use <code>v.x</code> and <code>v.y</code> instead of taking a pointer to them?&#8221;</p>
<p>Well first off, there aren&#8217;t really any sane C++ programmers. If you&#8217;re thinking that you could be an exception to this, you&#8217;re probably not sane or you might not be a C++ programmer. Maybe both.</p>
<p>Secondly, the idea behind them is that they&#8217;re variables. You use them the same way you would any other variable: to store results that you&#8217;ve computed or to pass data around. This means if you can boil down a long set of computations into a choice between members of a class, then you can avoid needing to compute it repeatedly and instead just pass a member pointer around.</p>
<p>Let&#8217;s see an example. We&#8217;re trying to write a function that takes in a <code>std::vector</code> of <code>Vector3D</code>s and adds a float to a component of each one. Now, which component is determined at runtime, so we have to pass it as a parameter to the function:</p>
<pre class="brush: cpp; light: true;">void add(std::vector&lt;Vector3D&gt; &amp; vs, int componentSelect, float amount) {
	for(std::vector&lt;Vector3D&gt;::iterator v_i = vs.begin() ; v_i != vs.end() ; v_i++) {
		switch(componentSelect) { // switch to determine which component to modify
		case 0:
			v_i-&gt;x += amount;
			break;
		case 1:
			v_i-&gt;y += amount;
			break;
		case 2:
			v_i-&gt;z += amount;
			break;
		default:
			break;
		}
	}
}

int main() {
	int componentSelect; // 0 means .x, 1 means .y, 2 means .z
	componentSelect = std::rand() % 3; // make a decision as to which one

	std::vector&lt;Vector3D&gt; vs(5, Vector3D(0, 2, 3)); // create five &lt;0, 2, 3&gt;s
	std::copy(vs.begin(), vs.end(), std::ostream_iterator&lt;Vector3D&gt;(std::cout, &quot; &quot;));
	std::cout &lt;&lt; std::endl; // print out the list
	add(vs, componentSelect, 1.f); // add 1.f to a component of each Vector3D
	std::copy(vs.begin(), vs.end(), std::ostream_iterator&lt;Vector3D&gt;(std::cout, &quot; &quot;));
	std::cout &lt;&lt; std::endl; // print out the list again

	return EXIT_SUCCESS;
}</pre>
<p>Example output:</p>
<pre>&lt;0, 2, 3&gt; &lt;0, 2, 3&gt; &lt;0, 2, 3&gt; &lt;0, 2, 3&gt; &lt;0, 2, 3&gt;
&lt;0, 2, 4&gt; &lt;0, 2, 4&gt; &lt;0, 2, 4&gt; &lt;0, 2, 4&gt; &lt;0, 2, 4&gt;</pre>
<p>The above naïve way involves this <code>int</code>→<code>Vector3D</code> component conversion for <em>each</em> element in the container. This is slow and involves a lot of code copying &amp; pasting. Moving the switch statement outside of the loop helps with the slow, but makes the code look even worse.</p>
<p>Member pointers to the rescue:</p>
<pre class="brush: cpp; highlight: [2,5]; light: true;">void add(std::vector&lt;Vector3D&gt; &amp; vs, int componentSelect, float amount) {
	static float Vector3D::* const componentPtrs[3] = {&amp;Vector3D::x, &amp;Vector3D::y, &amp;Vector3D::z};
	float Vector3D::*componentPtr = componentPtrs[componentSelect]; // select from array
	for(std::vector&lt;Vector3D&gt;::iterator v_i = vs.begin() ; v_i != vs.end() ; v_i++) {
		*v_i.*componentPtr += amount; // note: very little code duplication
	}
}</pre>
<p>Now you see that we can use member pointers to store the result of the component selection (the switch statement) and then operate on data using this stored result.</p>
<p>Note that I used <code>*v_i.*componentPtr += amount;</code> instead of <code>v_i-&gt;*componentPtr += amount;</code>. This is because <code>v_i</code> is a STL <code>iterator</code>, not a <code>Vector3D *</code>. This is where you see the <code>-&gt;*</code> operator (indirect <code>.*</code>) diverge from dereference-then-<code>.*</code>, as <code>iterators</code> do not need to define a <code>-&gt;*</code> operator but do need to define a dereference (<code>*</code>) operator. If you really want to use <code>-&gt;*</code> (and who doesn&#8217;t?), you&#8217;ll need to convert the iterator to a pointer first:</p>
<pre class="brush: cpp; highlight: [3]; light: true;">for(std::vector&lt;Vector3D&gt;::iterator v_i = vs.begin() ; v_i != vs.end() ; v_i++) {
	Vector3D *v = &amp;*v_i;
	v-&gt;*componentPtr += amount; // note the use of -&gt;*
}</pre>
<p>This is isn&#8217;t even the only way we could have done this: there are also a few tricks with templates or STL components like <code>&lt;functional&gt;</code> we could have used to the same effect, with varying amounts of ease-of-use and compile-time vs. run-time flexibility.</p>
<p>This is just another example of the bewildering flexibility C++ offers between performance and code readability, or if you like, between compile-time code execution and run-time code execution.</p>
<p><em>Stay tuned for more &#8220;Strange C++.&#8221; In the <a href="http://www.geekshavefeelings.com/posts/cs-and-operators-part-2">next issue</a>, we&#8217;ll discuss using member pointers to point to member functions, and how exactly using them will benefit our C++ applications.</em></p>
<p><em>You should read &#8220;<a href="http://www.geekshavefeelings.com/posts/cs-and-operators-part-2">C++&#8217;s .* and -&gt;* operators: Part 2</a>.&#8221; </em></p>
<ol class="footnotes"><li id="footnote_0_633" class="footnote">Of course, this is not including the indirect versions of the latter two, <code>-&gt;</code> and <code>-&gt;*</code></li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/cs-and-operators-part-1/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Seconds Wasted by Bureaucracy</title>
		<link>http://www.geekshavefeelings.com/posts/seconds-wasted-by-bureaucracy</link>
		<comments>http://www.geekshavefeelings.com/posts/seconds-wasted-by-bureaucracy#comments</comments>
		<pubDate>Tue, 20 Apr 2010 20:47:42 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[stuy]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=623</guid>
		<description><![CDATA[So in my senior year of high school, my school enforced a policy in which they checked student IDs upon entry to the cafeteria during lunchtime. I was very unhappy about this measure, as I am of all such policies that take a step towards turning my beloved Stuyvesant into a minimum security prison. Every [...]]]></description>
			<content:encoded><![CDATA[<p>So in my senior year of high school, my school enforced a policy in which they checked student IDs upon entry to the cafeteria during lunchtime. I was very unhappy about this measure, as I am of all such policies that take a step towards turning my beloved <a title="Featured article on Wikipedia, woot!" href="http://en.wikipedia.org/wiki/Stuyvesant_High_School">Stuyvesant</a> into a <a href="http://www.geekshavefeelings.com/posts/stuy-czar">minimum security prison</a>.</p>
<p>Every time I had my ID (and its affixed class schedule sticker) checked at the door, I made it a point to very obviously time the poor teacher doing his job with the stopwatch function on my Casio, and then record the time wasted by the check in a notebook I kept in my pocket. The following is the data I recorded:</p>
<table>
<tbody>
<tr>
<th>Date</th>
<th>Time wasted (s)</th>
</tr>
<tr>
<td>10/782/2006</td>
<td>17</td>
</tr>
<tr>
<td>10/783/2006</td>
<td>Not checked</td>
</tr>
<tr>
<td>10/786/2006</td>
<td>12</td>
</tr>
<tr>
<td>10/787/2006</td>
<td>5</td>
</tr>
<tr>
<td>10/796/2006</td>
<td>18</td>
</tr>
<tr>
<td>10/800/2006</td>
<td>12</td>
</tr>
<tr>
<td>10/801/2006</td>
<td>18</td>
</tr>
<tr>
<td>10/802/2006</td>
<td>10</td>
</tr>
<tr>
<td>10/803/2006</td>
<td>10</td>
</tr>
<tr>
<td>10/804/2006</td>
<td>12</td>
</tr>
<tr>
<td>10/808/2006</td>
<td>15</td>
</tr>
<tr>
<td>10/810/2006</td>
<td>10</td>
</tr>
<tr>
<td>10/811/2006</td>
<td>9</td>
</tr>
<tr>
<td>10/829/2006</td>
<td>9</td>
</tr>
<tr>
<td>10/830/2006</td>
<td>8</td>
</tr>
<tr>
<th>Total time wasted by this draconian step towards the gaping maw (s)</th>
<th>165</th>
</tr>
</tbody>
</table>
<p>Dates are recorded in October 2006 format; that is, the &#8220;day of month&#8221; is the number of days since September 30th, 2006. Days not in the table between 10/782/2006 and 10/830/2006 do not mean &#8220;not checked&#8221;&mdash;they mean that I didn&#8217;t eat lunch at the cafeteria on that day (I think).</p>
<p>As a warning, this post was useless, so those with time traveling capabilities will want to dial back 10 minutes to before they began reading this post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/seconds-wasted-by-bureaucracy/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I Am Now a Management Major</title>
		<link>http://www.geekshavefeelings.com/posts/i-am-now-a-management-major</link>
		<comments>http://www.geekshavefeelings.com/posts/i-am-now-a-management-major#comments</comments>
		<pubDate>Thu, 08 Apr 2010 13:32:16 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Class]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[comp.sci]]></category>
		<category><![CDATA[gatech]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=599</guid>
		<description><![CDATA[So I was just chilling and minding my own business during course registration for the next semester, when BAM I suddenly get a dangerous burst of ambition. I suddenly decide that I ought to take a class that was actually relevant to my major. I saw fit to not overreach myself, and instead maybe take [...]]]></description>
			<content:encoded><![CDATA[<p>So I was just chilling and minding my own business during course registration for the next semester, when BAM I suddenly get a dangerous burst of <em>ambition</em>. I suddenly decide that I ought to take a class that was actually relevant to my major. I saw fit to not overreach myself, and instead maybe take a demure class in C++, a language which I had studied and used for years.</p>
<p>My school was rather inclined to disagree with my petition for a &#8220;prerequisite override permit,&#8221; which is what I need in order to register for the C++ class, ECE 3090. After all, you couldn&#8217;t possibly learn C++ if you hadn&#8217;t first implemented some discrete FIR filters in the digital signal processing course first.</p>
<p>OK, just read my response after my registration permit was denied:</p>
<blockquote><p>Hi Xxxxxxx,</p>
<p>But I will lose interest in schoolwork and begin to find my course-load irrelevant and tedious. Soon I will feel as if I have lost my way, and either turn to religion and/or become a Management major. Either path will only further my anxiety about my capabilities and self-worth, and soon my very existence will come into question. I will wonder if school is worth my time, or if life is even worth living.</p>
<p>Years later, as I lay on a desolate sidewalk, a vagabond stranded by the School of Electrical &#038; Computer Engineering, tears will stream down my face onto my primary religious text and/or my diploma for my Management degree. It will be my last of many cold, lonely nights on that sidewalk. Hunger and sickness have taken its their final toll on my frame, already thin and abused since the second semester of Georgia Tech.</p>
<p>But as the world fades to darkness, I will realize that my tears are not of sadness, but of joy, joy that I had completed my core subjects instead of junior electives.</p>
<p>Oh, the humanities!</p>
<p>But seriously though: could I talk to the professor teaching the class next semester about getting a prerequisite override permit? I really am quite confident about the material in the course, and would like to take it to boost my GPA, and because I feel it is more relevant to my major as well as my interests and skill level overall.</p>
<p>Thank you,<br />
Xo Wang<br />
gtID: XXXXXXXXX</p>
<blockquote><p>On Tue, 06 Apr 2010 09:59:59 -0300, Xxxxxxx Xxxx <xxxxxxx.xxxx@ece.gatech.edu> wrote:</p>
<p>ECE does not override prerequisites for its courses.  Once you have<br />
successfully completed ECE 2025, 2030, and 2040, you can take ECE 3090.<br />
ECE 3090 is offered every Fall and Spring terms, and occasionally in the<br />
Summer.  You will have plenty of time to take it in the future.  Right<br />
now you need to concentrate on completing your core subjects, not junior<br />
electives.</p>
<p>Regards,</p>
<p>Xxxxxxx X. Xxxx<br />
Manager, Undergraduate Academic Advising<br />
School of Electrical &#038; Computing Engineering<br />
Georgia Institute of Technology<br />
PHONE: 404-894-XXXX<br />
FAX:   404-894-XXXX</p>
<blockquote><p>Below is the result of your feedback form.  It was submitted by xxx@gatech.edu (ZHAO WANG) on Monday, April 05, 2010 at 19:18:02.</p>
<p>grad_ugrad: Undergraduate<br />
term: Fall<br />
GTID: &#8212;&#8212;&#8212;<br />
course: ECE3090<br />
major: CMPE<br />
graduation_term: Spring<br />
graduation_year: 2013</p>
<p>comments: I already have knowledge of C++ and programming in 3090; previously held a job at a game graphics/AI company doing software engineering with C++.</p></blockquote>
</blockquote>
</blockquote>
<p>The response I got was essentially a straight-faced &#8220;no&#8221; and &#8220;go have yourself a terrible @#$%ing day&#8221; only without those specific words and phrased a lot less politely. Yes, less politely.</p>
<p>By the way, I&#8217;m not actually a Management major now. I&#8217;m just going to be an EECS who leans towards CS rather than EE. And hates life.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/i-am-now-a-management-major/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Mistakes to Make on a Raytracer</title>
		<link>http://www.geekshavefeelings.com/posts/mistakes-to-make-on-a-raytracer</link>
		<comments>http://www.geekshavefeelings.com/posts/mistakes-to-make-on-a-raytracer#comments</comments>
		<pubDate>Thu, 25 Mar 2010 19:10:11 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Class]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[comp.sci]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[processing]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=430</guid>
		<description><![CDATA[Writing your first classical ray tracer was at one point a big deal. Now I don&#8217;t see what&#8217;s so difficult about the dark side of computer graphics. Tray racing, as I call it, is a remarkably entertaining exercise that will become the future of gaming and 3D visualization as computing hardware catch up with our ambitions1. [...]]]></description>
			<content:encoded><![CDATA[<p>Writing your first classical ray tracer was at one point a big deal. Now I don&#8217;t see what&#8217;s so difficult about the dark side of computer graphics. <a href="http://www.youtube.com/watch?v=5J8pI8jobMo">Tray racing</a>, as I call it, is a remarkably entertaining exercise that will become the future of gaming and 3D visualization as computing hardware catch up with our ambitions<sup>1</sup>.</p>
<p>Simply put, ray tracing&#8217;s generating computer images through a physical simulation of light, by &#8220;shooting&#8221; <em>rays</em> from a viewpoint in 3D space and then &#8220;tracing&#8221; them along their paths for objects to draw on screen. Shoot a lot of them and you will have enough information for the screen.</p>
<p>This is far superior in quality and correctness, though also very much less efficient, than our current method of <em>rasterization</em>: gathering up all the objects we put into the virtual space, deciding what they should look like given a few arbitrary parameters, and then drawing them on the screen where we think they should go. Ray tracers produce such good-looking images, in fact, because they are <em>accurate</em>.</p>
<p>For an example, see Wikipedia&#8217;s exemplar specimen of ray traced work:<br />
<a href="http://en.wikipedia.org/wiki/File:Glasses_800_edit.png"><img class="alignnone size-medium wp-image-515" title="Glasses_800_edit.png from Wikipedia" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/Glasses_800_edit-300x225.png" alt="" width="300" height="225" /></a></p>
<p>If you need more convincing, check out a small company in California called <a title="Pixar at Wikipedia" href="http://en.wikipedia.org/wiki/Pixar">Pixar</a>. I believe they make these moving pictures or something.</p>
<p>&#8220;Now Xo,&#8221; you ask, &#8220;why did you call this wonderful ‘tray racing’ technique the ‘dark side’ of computer graphics? Surely it would be the ‘light side (no pun intended)?’&#8221;</p>
<p>No, it&#8217;s not. I learned rasterization first, I worked hard at some very pointless but very fast <a title="Raxo project page" href="http://www.geekshavefeelings.com/projects/raxo" target="_blank">software rasterizers</a>, and I just like it more. Shoot me (no pun intended).</p>
<p>Anyways, I wrote a simple &#8220;classical&#8221; (properly known as <a title="Turner Whitted on Wikipedia (there's no page for him?)" href="http://en.wikipedia.org/wiki/Ray_tracing_(graphics)#Ray_tracing_algorithm">Whitted</a>) ray tracer for CS3451<sup>2</sup> as an assignment. To my surprise, it took only eight hours of marathon coding to write, none of them daytime. The work consisted primarily of making and fixing simple mistakes that, once I had worked out the math, were <em>physically</em> incorrect.</p>
<p>That was the nice bit of it all; if you had a rendering error, you can just look at your model of the world and see if you did something in a way that makes no sense in the real world. Once I fixed those mistakes, I had a pretty nice ray tracer, if trivial by today&#8217;s standards.<br />
<a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/t2.png"><img class="alignnone size-thumbnail wp-image-519" title="A pretty standard image to be racin' trays for" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/t2-150x150.png" alt="" width="150" height="150" /></a> <a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/c4.png"><img class="alignnone size-thumbnail wp-image-517" title="Lots of inter-reflections and shadows. My friend TH said this didn't look right. I said to suck it." src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/c4-150x150.png" alt="" width="150" height="150" /></a></p>
<p><a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/c3.png"><img class="alignnone size-thumbnail wp-image-516" title="Pretty colors!" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/c3-150x150.png" alt="" width="150" height="150" /></a> <a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/c5.png"><img class="alignnone size-thumbnail wp-image-518" title="If you stare real hard, you can see your own face in a hall of mirrors. Spherical mirrors." src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/c5-150x150.png" alt="" width="150" height="150" /></a></p>
<p>These are the technical issues I stumbled on (and have stumbled on before; I don&#8217;t learn too well from my mistakes<sup>3</sup>), and ones you probably should watch out for:</p>
<ul>
<li><strong>Normalize your unit vectors!</strong><br />
Rays have directions representing their straight line path through space. These are usually represented with unit vectors. If you don&#8217;t keep them normal, then the distances you get through ray-object intersections will be inaccurate. This will cause issues if you actually depend on distances at some point, like when you do shadowing or light attenuation.</li>
<li><strong>Check for negative intersections!</strong><br />
When checking for ray-object intersections. Make sure you discard intersections that are <em>behind</em> the rays origin. Say that you parameterize your ray as <strong>o</strong> + <em>t</em><strong>d</strong>, where <strong>o</strong> is the ray&#8217;s origin, <strong>d</strong> is the direction (uuunit veeector!), and <em>t</em> is the scalar parameter indicating distance along the path given by <strong>o</strong> and <strong>d</strong>. If you get an intersection of <em>t</em> &lt; 0, discard the intersection.<br />
<br />Don&#8217;t do this:<br />
<a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/Negative-intersections.png"><img class="alignnone size-medium wp-image-524" title="Negative intersections" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/Negative-intersections-300x300.png" alt="" width="300" height="300" /></a></li>
<li><strong>Terminate your reflection rays by contribution!</strong><br />
When doing lots of bounces around shiny objects, that is, objects of constant of reflection <em>K<sub>refl</sub></em> &gt; 0, make sure to stop doing more bounces when additional bounces will contribute no visible difference to the image. My measuring stick here is by recursive descent along reflection rays: with each bounce, I multiply the contribution factor (which starts out at 1) by the <em>K<sub>refl</sub></em> of the intersected object. If the contribution of the next recursive level is less than 0.5/255, which is half the value of least significance for an 8-bit/channel output buffer, then I consider further bounces to be useless and terminate further recursion. It&#8217;s just a performance thing.</li>
<li><strong>Don&#8217;t let your reflection rays check against its own origin!</strong><br />
When bouncing reflection rays, be sure to <em>not</em> check for intersections against the object you just bounced it off of. It&#8217;s a simple way to avoid a rendering artifact known as surface acne<sup>4</sup>. However, this technique will prevent objects from casting <em>self shadows</em>, which are exactly what they sound like. Therefore, omit the reflection intersection check for the biggest thing in an object that does not self-shadow, e.g. spheres, triangles, planar polygons, etc. So if you are reflecting off an object composed of many triangles, <em>don&#8217;t</em> intersect the reflection ray against the triangle it bounced off of, but <em>do</em> check against the other triangles in the object.</li>
<li><strong>Intersect your shadow rays with geometry <em>and</em> lights!</strong><br />
OK, this is hard to describe, but it&#8217;s important. You check for shadowing by shooting a shadow ray towards the light you&#8217;re trying to err, check for shadowing against, right? If there is an intersection with another object, then there&#8217;s something blocking the light, right? Non monsieur! What if the light is between the two objects? For a shadow to be cast, the distance to the intersection must be <em>less than</em> the distance to the light.<br />
<br />Example: There is a light smack dab in between two spheres. It should look like this:<br />
<a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/Shadowing-done-right.png"><img class="alignnone size-medium wp-image-521" title="Shadowing done right" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/Shadowing-done-right-300x300.png" alt="" width="300" height="300" /></a><br />
<br />Except when it doesn&#8217;t:<br />
<a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/Shadowing-done-wrong-annotated.png"><img class="alignnone size-medium wp-image-522" title="Shadowing done wrong annotated" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/Shadowing-done-wrong-annotated-300x300.png" alt="" width="300" height="300" /></a><br />
<br />Just for the heck of it, let&#8217;s add more magic:<br />
<a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/More-magic.png"><img src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/More-magic-150x150.png" alt="" title="More magic" width="150" height="150" class="alignnone size-thumbnail wp-image-535" /></a></li>
</ul>
<p>So there you have it. Hopefully the technical bits in this post will help some poor uni student out there struggling to race his/her first tray, the writing has entertained you, and at the very least the pretty pictures got you all excited.</p>
<ol class="footnotes"><li id="footnote_0_430" class="footnote">Not meaning computers will get fast enough to simulate light realistically in real time; meaning they will make dining trays big enough to fit young adventurous men like myself</li><li id="footnote_1_430" class="footnote">Computer Graphics at Georgia Tech</li><li id="footnote_2_430" class="footnote">Unless I write it down with lots of parentheticals and footnotes like this</li><li id="footnote_3_430" class="footnote">See this article: <a href="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/Its-Really-Not-a-Rendering-Bug-You-see....pdf">It&#8217;s Really Not a Rendering Bug, You see&#8230;</a></li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/mistakes-to-make-on-a-raytracer/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My New Logo</title>
		<link>http://www.geekshavefeelings.com/posts/my-new-logo</link>
		<comments>http://www.geekshavefeelings.com/posts/my-new-logo#comments</comments>
		<pubDate>Tue, 23 Mar 2010 05:17:05 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Class]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[drawings]]></category>
		<category><![CDATA[logo]]></category>
		<category><![CDATA[stuy]]></category>
		<category><![CDATA[techtonics]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=486</guid>
		<description><![CDATA[I really dislike English class. I don&#8217;t dislike learning English, obviously, nor do I have any grudge against literacy or writing. What I really, absolutely cannot stand is the mind-numbing amount of thought that almost every English instructor I&#8217;ve ever had puts into a book which the author would have obviously not even suspected he [...]]]></description>
			<content:encoded><![CDATA[<p>I really dislike English class. I don&#8217;t dislike learning English, obviously, nor do I have any grudge against literacy or writing. What I really, absolutely cannot stand is the mind-numbing amount of thought that almost every English instructor I&#8217;ve ever had puts into a book which the author would have obviously not even suspected he meant to put into his writing.</p>
<p>I once had an English teacher at Stuyvesant who insisted with utmost sincerity that the character Kurtz of Conrad&#8217;s <em><a title="Heart of Darkness at Wikipedia" href="http://en.wikipedia.org/wiki/Heart_of_Darkness" target="_blank">Heart of Darkness</a></em> was so named because of its supposed phonetic similarity to &#8220;Christ.&#8221; Furthermore, Okonkwo of Achebe&#8217;s <em><a title="Things Fall Apart @ Wikipedia" href="http://en.wikipedia.org/wiki/Things_Fall_Apart" target="_blank">Things Fall Apart</a></em> has his name originate from our subconscious understanding of long, &#8220;masculine&#8221; vowel sounds. How could a syllable be masculine?</p>
<p>Her most far-fetched comparisons, which she dispensed daily with an unconquerable, belittling sneer, were the only ones which could match in tenuity to this little <acronym title="Something that makes your head hit your desk">headdesk</acronym> I was subjected to in junior year: &#8220;The jolly baker down the street has elected to use powdered sugar instead of granulated sugar. What do you think the author intended by such a decision fraught with between-the-lines intention?&#8221;</p>
<p>NOTHING. The author intended nothing!</p>
<p>So when I decided to create a new avatar for myself, my traumatizing experiences with English class led to me write the following disclaimer: &#8220;<em>I intended my work to be experienced as it has been created. I enjoy the way it looks, and this work has no further meaning beyond its initial appearance</em>.&#8221;</p>
<p>Then I looked at my new piece of work, the Outline:<br />
<img class="alignnone size-full wp-image-489" title="&quot;The Outline&quot; Personal Logo. Copyright © 2010 Xo Wang" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/xow_logo_128x128.png" alt="" width="128" height="128" /></p>
<p>Yes, I did make it the way it is because it looks nice. But it very obviously contains additionally meaning, much of it inherited from its sire, the <a title="Stuyvesant Techtonics" href="http://www.stuytech.com/" target="_blank">Stuyvesant Techtonics</a> (Stuy Tech/Techtie) logo (the Tech):<br />
<img class="alignnone size-full wp-image-490" title="&quot;The Tech&quot; Techtonics Logo. Copyright © 2008 Xo Wang." src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/techtonics_fixed_final.png" alt="" width="128" height="128" /></p>
<p>I wanted to retain the nature of my work, the hexagonal power button symbol that represents the melding of electronics and mechanics that is robotics. I discarded the dramatic red bar, standing out starkly against the black and white, because that was what Techtonics was when I made the logo—a bold sliver of a team, surrounded by uncreative soulless career-seekers. But I do not need such an iconoclastic representation; I&#8217;m a pretty quiet guy. Besides, taking out the red just makes it work better for my website. I removed the sharp caps in the bar and the five-sixths hexagon as well. Techtonics was an intense, competitive team; I am a person.</p>
<p>Of course, this means that I will be finally phasing out the remnants of my previous logo, the Indoor:<br />
<img class="alignnone size-full wp-image-491" title="&quot;The Indoor&quot; AKA &quot;AnimatedGameHardV3&quot; Personal Logo. Copyright © 2005 Xo Wang" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/AnimatedGameHardV3.gif" alt="" width="49" height="40" /></p>
<p>which has made its presence known only in its favicon form <img class="alignnone size-full wp-image-492" title="Old Favicon" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/old_favicon.ico" alt="" />, which is now replaced with <img class="alignnone size-full wp-image-493" title="New Favicon" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/favicon.ico" alt="" />. The new logo resized surprisingly well.</p>
<p>Previous iterations of the Indoor have looked like so:<br />
<img class="alignnone size-full wp-image-494" title="AnimatedGameHard Copyright © 2005 Xo Wang" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/AnimatedGameHard.gif" alt="" width="50" height="40" /> <img class="alignnone size-full wp-image-495" title="GameHard Copyright © 2005 Xo Wang" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/GameHard.gif" alt="" width="75" height="52" /></p>
<p>That last one is from 2003 or 2004. I believe I stole it from another website, because I remember it as originally animated. Please forgive me, other website. I was young, and you have done me a great service for the original art that has served me for so long. However, <a title="scioly.org - Science Olympiad Student Center" href="http://scioly.org/" target="_blank">scioly.org</a>, which is where I first began to use it, had and still has a very strict requirement on avatar file sizes, due to hosting costs. I cut all but one frame from it and simplified the palette. I eventually shaped the frame to look like <a title="One of my better planes in 2007" href="http://scioly.org/wiki/File:Gh0607WrightStuff.jpg" target="_blank">my own planes</a>, and animated the image once more to arrive at the final product, but I still wonder how the original looked&#8230;</p>
<p>Also, I found this amusingly terrible GIF bunched with the collection that the Indoor came from:<br />
<img class="alignnone size-full wp-image-496" title="AntiBush" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/AntiBush.gif" alt="" width="50" height="50" /></p>
<p>Wow. The things I did at the age of 13.</p>
<p>Now, you might ask, why do I need a personal logo? I really don&#8217;t. I don&#8217;t have that much of an ego to want a pictograph that represents me. The real issue was that I was using my Techtonics logo everywhere; my <a title="Gravatar" href="http://www.gravatar.com/" target="_blank">Gravatar</a>, my chat services, my computer login, etc. It was my only work of art that was at all notable. In fact, it was my only work of art that could be said to be a work of art.</p>
<p>However, I didn&#8217;t agree with the new Techtonics leadership after I left and they took the team over. I took issue with their interpretation of the principles of Techtonics (which is that there are none), as well as the low priorities they placed upon the various activities Techtonics traditionally participated in. I didn&#8217;t want to be using the same logo that represented <em>people</em> with whom I disagreed.</p>
<p>And that is how I know I am not an English teacher. My little picture actually represents real live people now.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/my-new-logo/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Fastest HQ9+ Interpreter in the World</title>
		<link>http://www.geekshavefeelings.com/posts/fastest-hq9-interpreter-in-the-world</link>
		<comments>http://www.geekshavefeelings.com/posts/fastest-hq9-interpreter-in-the-world#comments</comments>
		<pubDate>Sun, 07 Mar 2010 08:44:38 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[comp.sci]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=385</guid>
		<description><![CDATA[For some bizarre reason I felt compelled to spend hours of night writing an HQ9+ interpreter. Not just any HQ9+ interpreter, I thought, but the fastest HQ9+ interpreter in the world. Is that useless, you ask? Of course it is. The real purpose of HJMP1 (project page, GitHub page), which is what I&#8217;ve decided to [...]]]></description>
			<content:encoded><![CDATA[<p>For some bizarre reason I felt compelled to spend hours of night writing an HQ9+ interpreter. Not just any HQ9+ interpreter, I thought, but the <em>fastest HQ9+ interpreter in the world</em>. Is that useless, you ask? Of course it is.</p>
<p><img class="alignnone size-medium wp-image-417" title="useless-begins-with-u" src="http://www.geekshavefeelings.com/x/wp-content/uploads/2010/03/useless-begins-with-u-211x300.jpg" alt="Ends with S, too" width="211" height="300" /></p>
<p>The real purpose of HJMP<sup>1</sup> (<a title="GHF: HJMP" href="http://www.geekshavefeelings.com/projects/hjmp">project page</a>, <a title="GitHub: HJMP" href="http://github.com/GHF/hjmp" target="_blank">GitHub page</a>), which is what I&#8217;ve decided to call my new interpreter<sup>2</sup>, is of course for me to play with JIT compilation on different platforms.</p>
<p>Now that recent versions of GCC are freely available on x86 and AMD64 versions of Linux and Windows<sup>3</sup>, we programmers can use the same tools and code and target different platforms with the minimum of changes (and headaches!). However, those differences do accentuate themselves if you begin working closer to the metal, either because of requirements like performance or just for fun.</p>
<p>In this case, the distinction causing trouble was calling conventions. Regular 32-bit machines use <a title="Wiki: cdecl" href="http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl" target="_blank">cdecl</a>, which is straightforward and passes parameters to functions on the stack. Newer AMD64 software use variants of <a title="Wiki: fastcall" href="http://en.wikipedia.org/wiki/X86_calling_conventions#Microsoft_fastcall" target="_blank">fastcall</a>, which passes some number of arguments inside registers to take advantage of the doubled register count in AMD64 over x86. To make things more complicated, Microsoft uses their own unique AMD64 calling conventions for Windows and related tools.</p>
<p>Part of this exercise was to abstract away the general nastiness of writing—or generating—assembly code through object-oriented design. I accomplished this through the magic of dynamic<sup>4</sup> polymorphism. Different code emitters generating code for each platform talked directly with <a title="AsmJit" href="http://code.google.com/p/asmjit/" target="_blank">AsmJit</a>, the code generation library I used, but were hidden behind interfaces from the token processor. In addition, the token processors—one with JIT and one that executed token directly—were hidden from the parser (the <em>token generator</em>) as well through an interface, so that I can enable or disable JIT at runtime.</p>
<p>Overall, this little project was a success. It isn&#8217;t exactly groundbreaking or very useful for day-to-day work, but the experience of making it was a valuable one.</p>
<h3><a title="GHF: HJMP" href="http://www.geekshavefeelings.com/projects/hjmp">Download HJMP from the project page</a></h3>
<ol class="footnotes"><li id="footnote_0_385" class="footnote">pronounced &#8220;HIGH-JUMP&#8221;</li><li id="footnote_1_385" class="footnote">in addition to &#8220;The Fastest HQ9+ Interpreter in the World&#8221; <img src='http://www.geekshavefeelings.com/x/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li><li id="footnote_2_385" class="footnote">under <a title="TDM GCC" href="http://www.tdragon.net/recentgcc/" target="_blank">TDM GCC</a> and <a title="MinGW-w64" href="http://mingw-w64.sourceforge.net/" target="_blank">MinGW-w64</a></li><li id="footnote_3_385" class="footnote">and static too, really</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/fastest-hq9-interpreter-in-the-world/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Z Blogs!</title>
		<link>http://www.geekshavefeelings.com/posts/the-z-blogs</link>
		<comments>http://www.geekshavefeelings.com/posts/the-z-blogs#comments</comments>
		<pubDate>Sat, 20 Feb 2010 20:41:49 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[comp.sci]]></category>
		<category><![CDATA[stuy]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=477</guid>
		<description><![CDATA[Mike Zamansky, my high school teacher (computer science), mentor (everything), and all-around awesome guy (still everything!) is blogging! Check it: C&#8217;est la Z @ Blogspot]]></description>
			<content:encoded><![CDATA[<p>Mike Zamansky, my <a href="http://www.stuy.edu/">high school</a> teacher (<a href="http://cs.stuy.edu/">computer science</a>), mentor (everything), and all-around awesome guy (still everything!) is <a title="C'est la Z @ Blogspot" href="http://cestlaz.blogspot.com/">blogging</a>!</p>
<p>Check it:</p>
<p><a href="http://cestlaz.blogspot.com/" target="_blank"><img class="alignnone" title="Mr. Zamansky as... BILLY MAYS!" src="http://3.bp.blogspot.com/_7YN3bkG0cSc/SvtTgspDeXI/AAAAAAAAFYk/OFZX_CCXmDo/S220/billy_mays.jpg" alt="" width="178" height="220" /></a></p>
<h2><a title="C'est la Z @ Blogspot" href="http://cestlaz.blogspot.com/" target="_blank">C&#8217;est la Z @ Blogspot</a></h2>
]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/the-z-blogs/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>US International Dvorak</title>
		<link>http://www.geekshavefeelings.com/posts/us-international-dvorak</link>
		<comments>http://www.geekshavefeelings.com/posts/us-international-dvorak#comments</comments>
		<pubDate>Fri, 29 Jan 2010 23:16:45 +0000</pubDate>
		<dc:creator>Xo Wang</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.geekshavefeelings.com/?p=378</guid>
		<description><![CDATA[Windows (and many other operating systems) include by default an interesting keyboard layout called United States-International. It is essentially a version of the prolific American QWERTY keyboard layout, with many popular symbols and characters not found in English accessible through the AltGr key (or its Windows substitute, the right Alt key or Ctrl + Left [...]]]></description>
			<content:encoded><![CDATA[<p>Windows (and many other operating systems) include by default an interesting keyboard layout called <a title="Wiki: US-International Keyboard layout" href="http://en.wikipedia.org/wiki/Keyboard_layout#US-International" target="_blank">United States-International</a>. It is essentially a version of the prolific American QWERTY keyboard layout, with many popular symbols and characters not found in English accessible through the <a title="Wiki: AltGr Key" href="http://en.wikipedia.org/wiki/AltGr_key" target="_blank">AltGr key</a> (or its Windows substitute, the right Alt key or Ctrl + Left Alt) and through <a title="Wiki: Dead key" href="http://en.wikipedia.org/wiki/Dead_key" target="_blank">dead keys</a>.</p>
<p>I saw fit to create a Dvorak version of US-International, with the same deadkeys and combinations, but with the three touch-type rows rearranged to fit ANSI Dvorak. It should be an easy switch for existing Dvorak users and great if you&#8217;re starting out learning Dvorak.</p>
<p><strong>Keyboard layout installer for Windows 2000/XP/2003/Vista/7 (x86, x64, and Itanium):</strong> <a title="intldvrk.zip" href="http://www.geekshavefeelings.com/files/keyboardLayouts/intldvrk.zip">http://www.geekshavefeelings.com/files/keyboardLayouts/intldvrk.zip</a><br />
<strong>Microsoft Keyboard Layout Creator</strong><strong> source file:</strong> <a title="intldvrk.klc" href="http://www.geekshavefeelings.com/files/keyboardLayouts/intldvrk.klc">http://www.geekshavefeelings.com/files/keyboardLayouts/intldvrk.klc</a></p>
<p>The installer will add the layout to the Windows regional settings list of keyboard layouts, and is not some sort of driver, background service, or registry hack. It was made in <a title="Microsoft Keyboard Layout Creator" href="http://msdn.microsoft.com/en-us/goglobal/bb964665.aspx" target="_blank">Microsoft Keyboard Layout Creator</a>.</p>
<p>Anyways, with the US-International keyboard layout, nobody should have any excuse to type &#8220;u&#8221; or &#8220;ue&#8221; instead of &#8220;ü,&#8221; &#8220;2 x 4&#8243; instead of &#8220;2 × 4,&#8221; or &#8220;General Xo&#8217;s Chicken&#8221; instead of &#8220;General Xo’s Chicken.&#8221; Heck, maybe we could have prevented the creation of the English neologism &#8220;<a title="Wiki: Uber" href="http://en.wikipedia.org/wiki/Uber#Spelling" target="_blank">uber</a>.&#8221;</p>
<p>Of course, I do take issue with its lack of distinction between the hyphen (-), the en dash (–), and the em dash (—), and its lack of the prime marks (′, ″, and ‴) and the ditto symbol (〃). However, its existing variety of punctuation, accents, and other typographical symbols, including separate key combinations for the single closing quote (’), the typewriter apostrophe (&#8216;), and the acute accent (´), are easily enough to overwhelm the neophyte to ultra-elitist typographical pedantry (the sort I smugly enjoy).</p>
<p>Also, the dead keys themselves do get annoying. For example, Ubuntu Linux includes a layout called &#8220;USA International (AltGr dead keys).&#8221; That moves the dead keys to their AltGr combinations, so hitting the &#8216; key would produce a &#8216; straightaway, but to get the á (acute a) symbol, which is encountered far less frequently than the apostrophe, one would need to hit AltGr+&#8217;  and then A. Also of note is Ubuntu&#8217;s &#8220;USA Dvorak International,&#8221; which is not to be confused with my US-Internation Dvorak layout. It is simply the ANSI Dvorak layout with a few symbols available by AltGr; it is not, like my layout, a Dvorak remapping of the full US-International layout.</p>
<p>With that said, I&#8217;m not even a Dvorak typist. Heh.</p>
<p><em>Edit (10/1284/2006):</em><br />
I did some extremely cursory Googling, and came up with these two more Dvorak layouts based on US-International (created by others):</p>
<ul>
<li><a title="United States-Dvorak International at Jargon File" href="http://keyboards.jargon-file.org/#USID">USID at Jargon File</a> &#8211; Pretty much the same as my keyboard layout, except it came before mine. <img src='http://www.geekshavefeelings.com/x/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  <em>Update:</em> it appears that the layout&#8217;s apostrophe deadkey produces an acute accent (´) instead of an apostrophe (&#8216;); possibly other bugs as well.</li>
<li><a title="Dvorak international extended keyboard at Arjen van Kol" href="http://arjenvankol.com/dvorak.php">Dvorak international extended keyboard at Arjen van Kol</a> &#8211; Instead of using an exactly key-to-key mapping from US-International to ANSI Dvorak, this layout moves many of the AltGr-accessed special characters to be adjacent to other similar characters.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.geekshavefeelings.com/posts/us-international-dvorak/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.689 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2010-07-29 10:39:50 -->
<!-- Compression = gzip -->