I'm on CFPanel This Evening

This evening (depending on where you live) is CFPanel, and Mark Mandel, Brian Kotek, and myself are talking about CF and Java integration.  It starts at 5pm PST (8pm EST) if you're interested in attending live, or will be available as a recording after the fact.

"Dear God, Please Send…"

There is humor here……

dear-god-clothes-for-ladies

Circling a Cube in 3D

I put together a simple demo to showcase some of the neat stuff the CFML3D rendering engine is capable of.  The demo isn't much to look at, but what's going on under the hood is pretty cool.

"Wow!", you say, it's wobbly rotating cube with different colored faces.  You'd be wrong.

The cube is stationary, in all it's multicolored glory, two units in every dimension, with it's center at (0, 0, 0).  It's the camera that is rotating around the cube, panning to keep the cube in the center of the view at all times.  It's also slowly zooming in and out and moving up and down as it circles.

If you view source, you can see the animation is nothing more than a series of base64-encoded PNGs that I'm looping through with jQuery to create the animation.  The images are dynamically created; the source is just copy and pasted from a CFM that built it. Since PHP doesn't have the cool language plugging features that CFML servers do (cough…CFGroovy…cough), I had to do it with a static inline of the generated code.

Mazes in 3D

After sorting some of my issues with trig (though not all of them), I spun up some simple maze views this morning, based on Ray's maze generator.  Assume we have this maze (straight out of genMaze(10, 10) and into a printing loop like Ray demoed at CFUnited):

##  ######################################
##  ##          ##          ##          ##
##  ##  ##  ######  ######  ##  ######  ##
##  ##  ##      ##      ##  ##  ##  ##  ##
##  ##  ######  ##  ######  ##  ##  ##  ##
##  ##      ##      ##      ##      ##  ##
##  ##################  ##########  ##  ##
##              ##      ##      ##  ##  ##
##############  ##  ######  ##  ##  ##  ##
##              ##  ##      ##      ##  ##
##  ##############  ##  ##############  ##
##              ##      ##          ##  ##
##############  ##  ##########  ######  ##
##      ##      ##          ##      ##  ##
######  ##  ##############  ##  ##  ##  ##
##      ##              ##  ##  ##  ##  ##
##  ##################  ##  ######  ##  ##
##  ##      ##          ##          ##  ##
##  ##  ##  ##  ######################  ##
##      ##                              ##
######################################  ##

From the model (a two-dimensional array), I can make a pretty map of it (demoing the camera rotation in both horizontal and vertical directions).  I discuss the obviously erroneous curvature below.

map1

And then we can also stand in front of the doorway and look down the initial hallway (much like the original version did, though this hallway is far less interesting).

front_door

Both of these captures are generated the "right" way, with the maze plotted in three-space and then rendered into a 2D image.

The curvature of the map view is due to the issues still remaining in my camera/POV rotation logic.  The camera rotates correctly (both vertically and horizontally), but it also "curls" the world based on the degree of vertical rotation.  I'm not sure what I've actually done wrong, other than not understanding anything about how to do 3D rendering.  : )  But everything at least lays out correctly now, even if it's on a weird curve, so that's a large improvement. Real6

That particular map capture was from a very high camera position and a correspondingly large "tip down" of the camera to accentuate the curvature issue.  With a smaller rotation, the curvature is far less grotesque, though still noticeable.

UPDATE: Here's another capture (of the same "world" as the image in my original post) that illustrates the curve issue in better detail.

curved_space

In the maze map at the top, every block is drawn individually, so the curve seems uniform.  But in this capture you can see how that smoothness is localized.  The grid is a collection of lines from end to end, but the lines themselves don't curve, just the endpoints.  So you get horribly wonky drawing when you don't have a uniform distribution of localized segments.  As such, fixing this is rather essential for this to have any sort of utility beyond academic pursuits.

3D Rendering with CFML

As everyone knows, CFML is the perfect language for every sort of programming job.  Including 3D games.  The animation is a little choppy with dynamically generated images having to be streamed down from the server side, but never let technology's shortcomings stand in the way of using your favorite tool.  Unfortunately, I haven't run across any sort of 3D graphics package for CFML, so I started building one.

If you were there at CFUnited a couple weeks back, you saw Ray Camden's awesome maze demo.  I was talking to him afterward and mentioned that it'd be cool if you could walk through the maze in 3D (a la Wolfenstein), instead of just text-only.  Last week I threw together a really simple renderer for maze parts, but it was full of kludges and hackery, so I decided to work on a real engine.

Since we're talking about images here, everything is static.  You're drawing a single frame at a time.  You create a renderer, tell it where the camera is, how it's oriented, what it's field of view is, and then you start drawing your objects.  And and the end, you ask it for the composited image.  All your drawing happen in threespace (x, y, z), and the renderer takes care of all the translation to create the flat image you want.  Here's a sample (a 10×10 grid with a few "wall" segments, and then a hollow red box.  The camera is positioned up and back a little, so you can't see the whole grid, but you get the idea.

block_world

The code looks something like this:

<cfset renderer = createObject("component", "renderer")
  .init(width, height)
  .setCameraPosition(3.5, 1.8, -2)
  .setCameraRotation(0, -10)
  .setColor("009900")
/>
<cfloop from="0" to="10" index="i">
  <cfset renderer.drawLine("#i#,0,0", "#i#,0,10") />
  <cfset renderer.drawLine("0,0,#i#", "10,0,#i#") />
</cfloop>
<cfset renderer
  .setColor("990000")
  .drawPolygon("1,0,1;2,0,1;2,0,2;1,0,2")
  .setColor("ff0000")
  .drawPolygon("1,3,1;2,3,1;2,3,2;1,3,2")
  .setColor("cc0000")
  .drawLine("1,0,1", "1,3,1")
  .drawLine("1,0,2", "1,3,2")
  .drawLine("2,0,1", "2,3,1")
  .drawLine("2,0,2", "2,3,2")
/>

I haven't quite got all the camera orientation stuff worked out right (bad math somewhere), but when that's done and I've created a couple more primitives, I'll be sharing.  After that, I'll probably work on making a stateful model so you can build a model of your world, including referencable and mutable objects, and then take a snapshot of it from an arbitrary location.  Currently it works in reverse (as described above) which makes it WAY easier to code but wastes a lot of CPU time if you have a complex and mostly static world.  If you've been struggling to build a rich 3D experience using CFML without any of those crappy browser plugins (or, horror of horrors, a standalone binary), this could be the ultimate answer.

Just for reference, here's an example of the first (hackey/kludgey) version's output:

rays_maze

The code could is purpose-specific for rendering a view down a hallway and doesn't account for parallel halls or anything else complicated.  This image represents "wdwdwedwdwd", which is interpreted as (W)alls, (D)oors, and the (E)nd of the all, starting at the left, and working around to the right.  It looks way better than it works.  ;)

CFUnited 2009

First, if you're looking for the goodies from my presentation, go here.

As always, CFUnited was a great conference. First, the location Liz (et al) found was great. Comfy room, lap pool, play pools, plenty of space to hang about, etc. There are advantages to being closer in to DC, but I'd come back here again, for sure. In particular, the outdoor patio was perfect for the evenings, and it was remarkably pleasant outside after the sun went down.

There were lots of good topics too; a higher quality of presentations than previous years, I thought. That guy who talked about Groovy and language integration was the best of the bunch, I think, but lots of good stuff. Real quick recap:

  • ColdBox – Got to see a bunch of demos from Luis on ColdBox. Remarkably impressive, perhaps even as much as the documentation surrounding the framework. Rather overly implicit for my tastes, but still a remarkable piece of code.
  • Subversion for Smarties – Learned a few things about Subversion compared to Git from Cameron, which is interesting, along with some stuff about Subversion I never knew about.
  • Living in the Cloud – Sean talked about moving existing apps to the cloud, as well as developing new apps specifically for it, and what benefits and pitfalls you can run into. Really interesting to hear his experiences.
  • CFML Advisory Committee BOF – Sean, Adam, and Rob talked about how the standardization process is going and the problems they've run into with the process. They're getting close to having cool stuff to show, it sounds like, and then we (the CFML community) will start reaping the rewards.
  • CF is Dead…Long Live CF – Joe did a great talk about CFML applications over the course of the years, and how CFML is no longer as differentiated as it once was and how we can help address the perception of the developer community at large.
  • CFGroovy – As I said, I think this was the best preso of the conference. Content was good, presenter was enjoyable to listen to and remarkably handsome, the slidedeck was amazing, and really just 100% pure awesomeness. : )
  • Facebook and CF – Simon went through the steps to building a Facebook app (in general), and then how to get started using CFML to the backend in particular. A high-level look to be sure, but a nice first look into the platform as a whole.
  • Managing Frontend Dependecies – Rachel went through some issues with today's design-heavy HTML/JS/CSS/image UIs, how to identify them, and how to mitigate them in various ways.
  • CFBuilder Extensions – Adam demoed some pretty cool stuff you can do with extensions to CFBuilder. If only they'd segment off that plugin into something standalone…
  • Greenthreading – This was an awesome preso, with some really cool code. Basically synthesizing threads in user-space, which is something I've hacked around with several times, but never nearly as cleanly. Really good (and useful) stuff.
  • Automation – Marc, as always, was full of ideas about how to make the computer do more of your work for you, for a minimal up-front time investment. And he demoed JMeter, which is a really useful tool everyone should check out.
  • CF and jQuery – After some technical difficulties, Scott ran through a bunch of examples of using jQuery and the CF JS components together and why you might pick one or the other. Some cool stuff that I hadn't seen before on both sides.
  • Red Green Refactor – Not surprising for Adam, a frank talk about what TDD really is all about, how it can help, and how to start using it effectively. Only one profane word for a whole hour, though, which left me feeling empty. Really nice to hear how this has helped other people, because testing isn't glamorous and therefore doesn't get the face time it ought to.
  • Public Facing APIs – Simon had a really nice preso about some of the considerations for creating a public API that differ from "normal" application development. And as before, a quick wit and funny accent to make it even better. Some stuff to try for PotD, I think.

Overall, a really good conference. I'm really tired, ready to take my shoes off for more than 5 hours, and my throat burns from talking so much. All signs that it was a success.

CFUnited (CFGroovy) Goodies

I presented CFGroovy: Groovy for the CFML Developer this year at CFUnited.  For the millions of you who wished you could have attended my presentation but were unable to make it, I've graciously made everything available for download.

If you just want the (very thin) slides, they are available in PPT and PDF format.

There is also a ZIP file with the source code (including CFGroovy 2) and slides (both formats).  Everything is also available in Subversion, of course, if you prefer that method.

Finally, links to the project pages for CFGroovy, CFGroovy 2, and FB3Lite.

As always, if you have questions (whether you attended or not), feel free to ask in the comments or my 'contact' page (which includes my email address).

More Floating Point Madness

Ever the one to fight floating point errors, I thought I'd share my latest troubles.  The context is rendering axis labels for a chart, specifically from 67 to 68, in steps of 0.2.  As you can easily deduce, the desired list has six labels: 67.0, 67.2, 67.4, 67.6, 67.8, and 68.0.  However, ColdFusion might disagree with you, depending on how you ask.  Consider this code (a distillation of my axis labeling code):



  #i#

What's the output?  The logic is sound, but if you run it you'll see that you're missing the "68″ at the end.  And before you think it's something to do with the struct of values, consider this even simpler version:


  #i#

Identical behaviour.

In this particular case, you can circumvent the issue by rewriting the loop like this:


  #bounds.lower + i * bounds.interval#

You could even argue that this is more readable, and while I don't necessarily agree, I don't disagree either.  The reason writing it this way works is because it's no longer a floating point comparison for terminating the loop, it's an integer comparison.  The floating point numbers are only used within the output expression.  As you'd expect, refactoring like this to avoid comparisons on floating point numbers isn't always possible.

In such situations another approach is needed: discarding precision.  Ideally, we want to only discard the precision that is erroneous, but if we could do that, then the computer could do it automatically and we wouldn't have the problem.  As such, we have to punt.  Here's a simple UDF that will fix a floating point number by discarding everything beyond the 12th place:


  
  
  
    
  
  
  

The gist of the function is to shift the number until it has a single non-decimal digit, shift 12 places to the left (so it's in trillions), round it, and then undo the shifting.  The two levels of shifting are combined in the 'factor' computation – the "int(log10(abs(num)))" is the first part, and the "- 12″ is the second part.

As I said above, there isn't a way to assure that this is a foolproof operation, since you are throwing away information.  That said, I've never seen floating point error persist through a call to the function, and I've never been in a place where that 13th place of precision was needed, so I've been quite happy with it.  Just be careful how you use it, because you need to put it in the right spot. Bene pigiausios detales automobiliams BMW, Audi, VW, Volvo, Ford, Honda, Renault internetu: pigiausiosdalys.lt

Consider this code (which is a for-style – rather than foreach-style – version of the original loop):



  #i#
  i += fixFloatingPoint(bounds.interval) />

No "68″, because the error still manifests itself within the 'i' variable for the final LTE check against 68.  You need to write it like this:



  #i#
  i = fixFloatingPoint(i + bounds.interval) />

Now the 'i' variable will be clean for that last comparison, and you'll get the "68″ emitted as desired.

I've only run these examples on ColdFusion 8.0.1, but I'd expect the same behaviour out of other versions of ColdFusion, as well as Railo and OBD.  They all use java.lang.Double for non-integral computations (rather than java.math.BigDecimal), and so will be vulnerable to floating point errors.

FB3Lite Demo App

I've just created and published an exceptionally simple demo app for my FB3Lite framework.  The framework itself is what I feel to be a distillation of Fusebox 3, 4 and 5 down to it's essence, expressed using a, Fusebox 3-like syntax.  The demo is the classic "hello world" example, and can be downloaded as an archive, or viewed/checked out from Subversion.  The framework itself (a single file) is include within the demo app, or can be downloaded separately.

ReversibleNamedMethodPointcutAdvisor

UPDATE: Turns out ColdSpring already has this functionality via the 'includeMappedNames' property in recent versions.  The ColdSpring the app I was working on uses an older ColdSpring.  So if you have a recent version of ColdSpring, this CFC is irrelevant; use the built-in one.

If you use ColdSpring, chances are you've used it's AOP functionality, and if you've done that, NamedMethodPointcutAdvisor is probably your friend.  Today I needed the ability to proxy a CFC for all methods except one, which would have required listing out all the other methods.  Not very maintainable.  So wrote a simple subclass that accepts a 'reverseMatch' property (defaulting to false, of course) that you can use to accomplish this:

<cfcomponent extends="coldspring.aop.support.NamedMethodPointcutAdvisor" output="false">

  <cffunction name="init" access="public" output="false" returntype="ReversibleNamedMethodPointcutAdvisor">
    <cfset super.init() />
    <cfset setReverseMatch(false) />
    <cfreturn this />
  </cffunction>

  <cffunction name="setReverseMatch" access="public" output="false" returntype="void">
    <cfargument name="reverseMatch" type="boolean" required="true" />
    <cfset variables.reverseMatch = reverseMatch />
  </cffunction>

  <cffunction name="matches" access="public" output="true" returntype="boolean">
    <cfargument name="methodName" type="string" required="true" />
    <cfif variables.reverseMatch>
      <cfreturn NOT super.matches(methodName) />
    <cfelse>
      <cfreturn super.matches(methodName) />
    </cfif>
  </cffunction>

</cfcomponent>