Home

Advertisement

Customize

Moving graphics with trigonometry

Mar. 28th, 2009 | 09:38 pm

http://bojordan.com/log/?p=691

Notice: This is intended to involve only very basic concepts.

No matter the scope, most “game” programming these days involves moving pictures around on a computer screen, and performing this task can be very easy with a little basic math (specifically, trigonometry). Small two-dimensional graphics in games are usually called “sprites”, and in this exercise we’ll simply move a sprite.

We will be plotting a trajectory of a sprite across our screen, and to do this we keep track of

  1. the sprite’s position (a single point containing its X and Y coordinates),
  2. a velocity,
  3. and an angle at which to plot the distance the sprite travels.

Our game will draw the sprite to the screen as fast as it can, and we will know how much time has elapsed since the last time we drew the sprite. So, we will be provided the final number we need to plot our new sprite position: elapsed time.
We are calculating a distance vector, which is basically a line from one point to another. If our sprite’s velocity is five pixels per second, and one second elapses, it will travel a distance of five pixels. However, what is the new X,Y position of that point? It depends on the angle!

To calculate the amount along the X and Y axes our sprite has traveled, perform two simple calculations:

distanceX = velocity * elapsedTime * cos(angle);
distanceY = velocity * elapsedTime * sin(angle);

pointsAdd these values to the previous X,Y position of the sprite and you’ll have the new position of the sprite. The diagram assumes a starting position of (1,1), and shows two distance vectors: The red is with an angle of π/4 radians (or 45º from vertical), while the green is an angle of π/2 radians (or 90º from vertical). Both have the same velocity magnitude.

To add a little simple rebound off the sides of the screen, make sure that the X and Y coordinates of the sprite are not beyond the edges. For a screen 800×600 pixels, where directly up is an angle of 0, simple reverse the angle when the sprite goes off the left or right of the screen, and subtract the angle from PI when it goes off the top or bottom.

if (xPosition > 800) {
    xPosition = 800;
    angle = -angle;
}
if (xPosition < 0) {
    xPosition = 0;
    angle = -angle;
}
if (yPosition > 600) {
    yPosition = 600;
    angle = PI - angle;
}
if (yPosition < 0) {
    yPosition = 0;
    angle = PI - angle;
}

To slow the sprite down at a certain rate of deceleration, simply subtract from the velocity an amount that is multiplied by the elapsed time: </pre>

velocity = velocity - (deceleration * elapsedTime);

This isn’t the most accurate of physics demonstrations, but surprisingly advanced games can be built around calculations as simple as these.

Next we’ll discuss how to derive a distance from two points, and soon go over some handy linear interpolation.

Link | Leave a comment | Add to Memories | Tell a Friend

Get Windows key on an old keyboard

Jan. 17th, 2009 | 06:29 pm

http://bojordan.com/log/?p=647

I have a particular love of IBM keyboards, both the clicky Model M (compact) as well as scissor-key ThinkPad keyboards. Neither of these, however, has a Windows key. This key is good for much more than popping up the Start menu, so I’d like to get it back. Also, I never use Caps Lock, and have always preferred having Control in that location. So, I remapped Left Control to the Caps Lock key, and then reassigned Left Control to work as Left Windows. Works like a charm.

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,1d,00,3a,00,5b,e0,1d,00,\
  00,00,00,00

Explanation of the code to put into the registry can be found here, or you can just use KeyTweak to reassign.

Link | Leave a comment {5} | Add to Memories | Tell a Friend

Back to speed, even if slowly

Jan. 12th, 2009 | 07:54 pm

http://bojordan.com/log/?p=639

Some months ago, I tweaked a hip flexor during an impromptu trail race. I didn’t give the injury proper respect, instead drawing out my recovery much longer than it should have taken. Furthermore, adjustments in my stride resulted in development of a very annoying plantar fascia cyst.

Now, as I’m training my way back into shape, I’m experiencing some extreme tendonitis in my right ankle area. Initial icing and mild anti-inflammatories were doing the trick, but it got worse over the weekend. Just as I was ramping up to 50-mile weeks. So depressing!

So what have I learned from the past year? First, I should give injuries proper respect. Part of what makes endurance athletes special is their constructive tolerance of pain. I pride myself in this, but I need to get better in distinguishing constructive and destructive pain tolerance. I need to listen. So, I’m taking at least most of a week off, even though I have a marathon date bearing down on me.

Second, I’ve really let my core conditioning go. I hate lifting weights when it’s not part of a routine, so I must find a new routine that includes core. Skimping on core strength is so common for runners, and has to be one of the most counterproductive things a runner can do.

I’m signed up for Birmingham, Albany, and Boston. The coming weeks will tell when my next attempt at a personal best should happen. It doesn’t have to be soon.

Link | Leave a comment | Add to Memories | Tell a Friend

Sync two iTunes libraries

Oct. 11th, 2008 | 08:02 pm

http://bojordan.com/log/?p=604

I have two Macs, and I use iTunes on both of them. My music library is managed on my MacBook, but I want access to all of the music on my Mac Pro at home without having to stream it. What’s the easiest way to keep these synchronized? We’re dealing with a Unix, so rsync comes to the rescue:

  1. Please back up your music, in case you get the hosts swapped or something. Tar it up or something:
    tar -zcvf myMusic.tar.gz Music
  2. Make sure one computer is available to the other via SSH by enabling “Remote Login” under System Preferences/Sharing. Grab a terminal and test this:
    ssh userid@hostNameOrIPAddress
  3. Also in the terminal, in your home directory, try a test run of rsync. I am transferring files from my laptop to my desktop, from a terminal on the desktop, so the command is:
    1
    2
    3
    
    rsync --archive --verbose --rsh=ssh --progress
        --log-file=anyNameYouLike.log --dry-run
        my-macbook.local:Music/iTunes .
  4. Add additional -v flags to get more verbose output. Run until you feel comfortable. Take off the --dry-run and sit back.
  5. Lastly, go select “File/Add to Library…” in iTunes and select your Music/iTunes directory. It’ll churn through the files and update its local database.

Update:
Turns out, these days I hardly ever rsync between two Macs; I buy music and rip CDs into my laptop, and I have a Sonos system that accesses tunes via a shared drive attached to my network. I easily mount this drive share to my laptop, so it regularly shows up in /Volumes on my laptop. So, the rsync command line looks like I’m synchronizing two directories local to my laptop:

cd Music/iTunes
rsync --archive --verbose --stats "iTunes Music/" "/Volumes/NAS/iTunes Music/"

Link | Leave a comment | Add to Memories | Tell a Friend

C# tip: Touching brain with reflection

Sep. 28th, 2008 | 03:37 pm

http://bojordan.com/log/?p=602

In the interest of speed, I’ll start with a list of truths I won’t be discussing at length:

  1. Some day you will need to address a problem in someone else’s libraries without the luxury of patching and recompiling their code.
  2. Most people know .NET reflection allows you to interact with types you didn’t have access to at compile time. It also allows you to interact with types you don’t have permission to directly address in code (internal classes, private members, etc.).
  3. .NET Reflector is an essential tool for any C# developer who uses someone else’s API. Which is everybody.

Using reflection to read members and invoke methods is easy:

  1. Get an instance of System.Type from your object. All objects have a GetType() method.
  2. Call Type.InvokeMember(), passing in the instance you’re wanting to manipulate as well as the name of the member and access flags.

Real-world

The XNA framework is a delightful graphics and games programming API by Microsoft, which is free (as in beer) but not open-sourced, and is officially unsupported. I play a bit with XNA and recently came across a serious performance killer in XNA 2.0 (which I’ve been assured is fixed in 3.0 final; forum post here and bug report here). Basically, there is a leaky dictionary embedded two internal classes deep that never gets cleaned up, framerate goes poop in a little while if you’re loading and unloading content like crazy.

So, inside the public GraphicsDevice class, there is an instance of an internal DeviceResourceManager, and inside this is the collection of internal ResourceData structs which never gets cleaned up. Once the content that’s being tracked has been disposed, its ResourceData instance can go away, so we’re going to periodically poke into this collection and flush items that are slowing down access to the collection.

In our code, we have easy access to the public GraphicsDevice. So, let’s get access to an instance of the internal DeviceResourceManager inside of it, which is a private instance named “pResourceManager”:

Type graphicsDeviceType = this.GraphicsDevice.GetType();
object deviceResourceMgrInst =
    graphicsDeviceType.InvokeMember("pResourceManager",
        BindingFlags.NonPublic | BindingFlags.GetField |
            BindingFlags.Instance,
        null,
        this.GraphicsDevice, // the instance we're manipulating
        null);

So, we have access to a private instance of DeviceResourceManager. Now, we go inside it in the same way to get the private collection:

Type deviceResourceMgrType = deviceResourceMgrInst.GetType();
System.Collections.IDictionary resourceDataDictionaryInst =
    deviceResourceMgrType.InvokeMember("pResourceData",
        BindingFlags.NonPublic | BindingFlags.GetField |
            BindingFlags.Instance,
        null,
        deviceResourceMgrInst,
        null) as System.Collections.IDictionary;

Inside the class there is a sync object for locking as we address the dictionary, but now we know how to get access to that and use it. Then, we can iterate over the objects in our dictionary and remove the ones that are no longer in use.

That’s all the magic. Use this sparingly, as the performance of addressing objects via reflection is horrendous, and it’s always dangerous to subvert API access declarations. However, it might be just the thing that saves you in a pinch.

For the curious, the continued code for the XNA 2.0 leak work-around:

Read the rest of this entry »

Link | Leave a comment | Add to Memories | Tell a Friend

Davidson Half-marathon

Sep. 25th, 2008 | 02:35 pm

http://bojordan.com/log/?p=601


All out at the Davidson half-marathon finish
(thanks to Jeri for picture)

Fun race last weekend in Davidson. Most of Crazy Legs showed up and we even got a few age group awards. I was 13th overall with a 1:25:35, good for an age-group second in my first race in the 35-39 group (congrats to fellow CL Paul Gonzalez for getting first about a minute ahead; I was no match for him in on the hills).

Link | Leave a comment {3} | Add to Memories | Tell a Friend

C# tip: Dependency Injection on the cheap

Sep. 18th, 2008 | 04:05 pm

http://bojordan.com/log/?p=597

I want to keep this post short, so I won’t go into why you should design your code around interfaces, or why injecting dependencies at runtime is such a good idea. Rather, if you’re using .NET and want to quickly use Dependency Injection in your design, but are hesitant to adopt yet another framework (like Spring.NET, which I heartily recommend) for whatever reason, look to System.Activator.

In the way I usually use Activator, you need:

  1. The path to the assembly containing your implementation. The magic here is that you don’t need this referenced anywhere in the original application (you know, Dependency Injection and all).
  2. The name of the implementation class you want to load. I’m actually going to traverse all of the types in the injected assembly, which isn’t necessarily the most secure or efficient way to do things, but it is convenient and works well.

Namespaces used:

  1. System.Activator, to create the instance from a loaded assembly
  2. System.IO.FileInfo, to conveniently get the full path to the assembly you want to load
  3. System.Reflection.Assembly, to load your assembly (inject the dependency) into the current app domain

Some code:


  IPluggableDependency pluggableInstance = null;

  // Load the injected assembly with its absolute path
  FileInfo assemblyFile = new FileInfo("PluggableStuff.dll");
  Assembly assembly = Assembly.LoadFile(assemblyFile.FullName);

  // Find the matching Type you're wanting to instantiate
  foreach (Type type in assembly.GetTypes())
  {
    if (type.FullName == "PluggableStuff.ClassName")
    {
      // Create an instance of your implementation,
      // cast as an interface
      pluggableInstance = Activator.CreateInstance(type)
        as IPluggableDependency;
    }
  }

Now, as I said before, look into using a lean, established, flexible, robust DI framework like Spring. However, if that’s not an option for whatever reason, you can still build your apps around a nice DI pattern. Future migration to Spring will be a snap.

Link | Leave a comment | Add to Memories | Tell a Friend

Blue Ridge Relay 2008

Sep. 13th, 2008 | 03:26 pm

http://bojordan.com/log/?p=588

Last weekend was the Blue Ridge Relay, which is 209 miles and 24+ hours of sick quad- and hamstring-bashing. Our Crazy Legs team showed up with a full twelve-person roster, and pulled out an impressive seventh-place (out of 75+ teams) in 26:45.


The view from “Goat Hill”, somewhere in the Blue Ridge Mountains

I ran position eight, with a first leg of 4.5 miles (moderately hilly), which I tried to run at my 5k pace. My overnight leg was 8 miles (nightmare dark mountain up, up, up, then screaming down), during which I experienced repeated heartburn worse than any college beer and wings episode. A sunburn and a general lack of sleep during the preceding week almost got the better of me before the night run, but passing a bunch of people delivered enough oh-so-lovely adrenaline to keep the feet turning over.


Mike “Goat” Smith cranking Goat Hill

At the top of Goat Hill, I got the hand-off for my last leg, which was 9.4 miles downhill with over 2000 feet of descent. I cranked it as best I could, averaging sub-6s. My quads were destroyed for a week.

Prior to downhill bash (thanks Cheryl for the pic)


Coach Tino rounding the corner for the finish

The finish was in downtown Asheville. Luckily, the downtown Y allowed participants to shower afterward, so everyone was able to survive the ride back to Charlotte.

Two vans’ worth of Crazy Legs

I’d go on about how fun the team was, but it would mostly be “you had to be there” stuff. Which, of course, is what makes these sorts of things worthwhile. I fully expect to run this event again, probably with much the same crew, and preferably as an ultra team (running more, but avoiding all the waiting around). Also, I’ll get more than three hours of sleep the night before the race next time.

I have a bunch more pictures at this link, and Mike’s Flickr archive is at this link.

Link | Leave a comment | Add to Memories | Tell a Friend

McMullen tempo, speedwork, shoes

Jun. 14th, 2008 | 11:33 am

http://bojordan.com/log/?p=584

Started out the new running week (running weeks start in Saturday) with McMullen Creek from 51 all the way to Rea (including the steeplechase construction portion at Johnston). PM was up for a 6:30am start, which was a good thing since the lot was already starting to get busy. DJ showed up and seems ready to resume his Boston quest this year, and PM’s friend R joined us for the first time, and according to PM was there specifically to “kick my ass”; good thing I brought my heart rate monitor for the first time in over a year!

First six out were mild 8:15-ish miles, and I stuck a solid 120bpm all the way out. R and I took off on the way back, intending to run about a five-minute negative split, but we ended up running mid-to-low 6’s (I think) for 4.5 miles; all I’m sure of is that I was at 140bpm for the first two tempo miles, 150 for the third, and then popped 160 over the last mile. He seemed to have plenty of speed left, but I was pushing all out. Awesome getting to chase, which is exactly what I need to get some speed for the Fall. Nobody human runs 2:50 marathons at a 120 heart rate, after all.

Plus, R is on our Blue Ridge Relay team, which means I won’t be the fastest on the team. Sweet! I’ll still happily take spot 2, which is going to bring a new meaning to the name “Crazy Legs”.

In other running news, speedwork on the track has gone well for the past two weeks, though I might finally puke the next time we do 10×400m in 100F temp. Asics finally released the new rev for my favorite racing shoe, the Gel-Speedstar 3, and I have a pair on order. I’ve been doing my speedwork in some new two-models-old DS Trainers I pulled out of the closet and might try the new ones if I don’t love the Speedstar 3 like I did the 2.

Link | Leave a comment {2} | Add to Memories | Tell a Friend

Leica M8 review by a real photojournalist

Jun. 13th, 2008 | 12:08 pm

http://bojordan.com/log/?p=583

Michael Kamber is a war photojournalist and Leica fan currently operating in Iraq, and in this article he discusses his real-world experiences with the Leica M8. The article is scathing, to put it bluntly. Most interesting to me were not the photographic problems with the camera (absolutely wild fluxuations in color balance, for example) but some very basic usability flaws that rendered the camera unusable for Kamber. In a statement that sounds so familiar to me, he questions whether Leica performed any real-world testing of the camera before shipping. And this guy’s not just being picky.

Originally linked from Luminous Landscape.

Link | Leave a comment | Add to Memories | Tell a Friend

Kate Portrait

May. 31st, 2008 | 01:27 pm

http://bojordan.com/log/?p=581

I love this portrait my sister is doing of my niece. She says it’s a work-in-progress, though I’m in favor of her keeping it in its current state.

img_5279-450.png

I can’t wait to see the companion portrait of my nephew. She paints from photographs, so I’m hoping I can provide a similar portrait of him.

Link | Leave a comment {3} | Add to Memories | Tell a Friend

Boston 2008

May. 21st, 2008 | 11:06 pm

http://bojordan.com/log/?p=579

I’m not sure exactly why I’ve waited a month to write about Boston. Perhaps it was my almost complete lack of photo-taking. More likely, it’s the feeling that I had finally completed a major undertaking, which leaves me exhausted and satisfied for about a week, then the elation turns into nervousness as I realize that I need another goal. New goals are scary, especially considering I had five years to get comfortable with this one.

To put it simply, the Boston Marathon is the best marathon in the entire world, in practically every way. It lives up to every expectation, from the talent level of the field, the difficulty of the rolling course, to the crazy pre-race expo and festivities, to the absolutely mind-blowing crowd support.

The course is every bit as hard as people say, with a quad-crushing downhill trend for the first half, and then crushing uphills for about six miles until 22. I was a bit out of shape for a fast attempt, but I still went out a little fast, loving the opportunity to flow along with huge packs of runners my speed or faster. I honestly got a tiny bit discouraged around half-way, as I’m not accustomed to being continuously passed by entire packs of people, and this trend didn’t let up for the entire race. But even that was incredible, running in a crowd for an entire marathon.

boston2008_450.pngUncomfortably rounding one of the last corners

I’ve never seen crowd support anything like this. Honestly I wonder why so many people turn out, as they are out in decent numbers for the entire course, and in huge crowds through the towns. Children were hanging out of trees, people were barbequeing, college kids were insane. I had heard the stories of the Wellesley girls, but nothing could have prepared me for what sounded like a Beatles concert a half-mile away. I’d go back just for that.

Unfortunately I didn’t quite have the legs I had in Portland or Myrtle, and the weather turned out to be a bit hot and sunny for me, so the hills and sun took their toll on me. No mushroom clould, but running sub-3 was definitely out of the question, so I managed to hold on for a Boston-qualifying 3:13 (Note: I’ll be 35 next year, so I get five minutes, and yes, I was already qualified for ‘09). Unless my dad qualifies for ‘09 (he will definitely be there for ‘10; more on that later), I’m going to try to kill this course next year. Revenge on those hills will be sweet.

pic-0002-edit.pngPossibly the perfect restaurant? Must try it in ‘09

For the entire weekend there are runners everywhere, and you can tell they’re serious runners. Everyone wears bragging gear from previous races, or they’re already wearing a wind jacket for the current race. Thousands and thousands of people, all excited to be there. If you are a runner, really a runner, you must do Boston at least once. It’s not just the reputation, it’s a religious experience. And if you aren’t a runner, I don’t know how you could experience the Boston weekend and not be one by the end of it. Just ask Jeri, Susi, or either of the Pauls.

Link | Leave a comment | Add to Memories | Tell a Friend

Happy sandboxes and svn switch

May. 8th, 2008 | 09:54 am

http://bojordan.com/log/?p=574

I encourage everyone I work with to keep all of their development code in a source repository, even one-off dead-end prototype code they’re not going to check back into a main development tree. If you know you’re going to do destabilizing work, of course you’ll create a sandbox branch from the development branch and then do your work; we all know this. So, what happens if you inadvertently end up with a dead-end prototype in your working source checkout, and you didn’t have the foresight to start with a branch? It’s easy to make it as if you had.

Disclaimer: Of course, if this all fails you could lose a lot of work, so you might want to generate a quick diff or backup just in case. Just be careful.

  1. Create a development branch in our repository on the server. We are using Windows and TortoiseSVN, and our working code is from the branch at svn://svnserver/MyProject/Trunk at revision 1942. So, we use the Repo-browser in TortoiseSVN to find Trunk, select revision 1942 from the upper right-hand corner of the dialog, and then select “Copy to…” with a new location at svn://svnserver/MyProject/Sandboxes/bojordan/DeadEndPrototype. We now have a new branch, but our working code still belongs to Trunk.
  2. Right-click on my top-level checkout directory, select “Switch” from the TortoiseSVN options, and select the new branch in the “To URL:”. We know HEAD is fine, as we just created the new branch.
  3. Now, the next time we commit our code, we’ll check it back into the new branch. Glee!

Just remember: No more stale development tree archives on your development machines means cleaner, uncluttered living, and might get you one step closer to a 16 minute 5k. Or, maybe not, but you’ll still be happier.

Link | Leave a comment | Add to Memories | Tell a Friend

Scraping together Boston training

Apr. 7th, 2008 | 10:24 pm

http://bojordan.com/log/?p=571

I have my first Boston Marathon on April 21, and I’m not even remotely ready. I take some comfort in knowing Boston is more a reward than another proving ground, but I still want to give it a tough effort and I’m simply not ready. I ran my marathon PR almost completely solo at Myrtle Beach, and there are thousands of runners my speed or faster at Boston to push me. However, considering my low recent mileage, lack of speedwork, and an inconvenient extra five or so pounds, I should be very happy with a 3:10 (over ten minutes slower).

Honestly, I wish my Boston time didn’t matter to me, but I know myself better than to think I can completely coast it. I can only hope I have enough training base to survive the adrenaline rush I’m going to feel for the first 18 miles. Here’s to going until the wheels fall off! Watch for the mushroom cloud!

Link | Leave a comment {2} | Add to Memories | Tell a Friend

Upcoming races

Mar. 1st, 2008 | 08:03 pm

http://bojordan.com/log/?p=570

I don’t have major running plans solidified for the rest of this year, other than the obvious highlight that is my first Boston Marathon on April 21. I am looking forward to running a number of half marathons this year, and was expecting to run the Corporate Cup again but will miss it due to a snowboarding trip. Racefest at SouthPark is only a little more than a week before Boston, so I question whether a hard effort there would be wise.

My dilemma? I was hoping to have a NYC qualifying time for guaranteed entry before the May 1 deadline. I’m definitely capable of the 1:23 qualifying time for the half marathon, but I don’t want to jeopardize Boston. The marathon time of 2:55 would be highly ambitious at Boston, but I may consider attempting it if my training goes well. I probably won’t have another half marathon chance before the end of the month, assuming I could even muster the energy.

I want to pick up some speed over the summer, which usually means shorter, more frequent races. I have no idea what’s available in the summer, though Tim’s Ramble Tail Half Marathon at Uwharrie on May 17 is likely.

Returning to Grandfather (July 12) and getting my revenge on San Fran (August 3) would be enormous fun, though this might be prime speed-building time.

Later in the year I’ve committed to running a hard-core leg for Coach Tino at the Blue Ridge Relay on September 5 and 6, and then we have the Crazy-MFn-Legs October Classic two-day expedition (two marathons, one weekend). No time records will be set at either of those, though balls-of-steel bragging rights will be significant.

I would like at least one fast full marathon attempt in the Fall. NYC on Nov 2? Chicago on Oct 12? Portland on Oct 5?

Link | Leave a comment | Add to Memories | Tell a Friend

Crowders fun (and a record bonk)

Mar. 1st, 2008 | 07:01 pm

http://bojordan.com/log/?p=567

Late last week Mike Smith pointed me toward a Sunday morning Crowders Mountain meet-up on the Native Trail Gods list, organized by Tim Long. I’m always a sucker for runs at Crowders, and the thought of a group run on my favorite local trail was too much to resist. Nevermind the soreness I felt through the week after Myrtle Beach, or the difficulty I had on my Saturday 15 miler. Fun to be had.

Greg, Shashi, and Tim showed up; Tim placed sixth overall at Uwharrie in the 40-miler, so I expected to be left behind fairly quickly. However, everybody’s pace was moderate and I was able to hang with the crew all the way up the fire road, feeling stronger the farther up the mountain I got. After such a strong climb, picking up the pace for the entire white trail out and back was a big thrill. Little did I know the confidence I was gaining was due to my body blatantly lying to me, but it was amazing fun while it lasted.

Read the rest of this entry »

Link | Leave a comment | Add to Memories | Tell a Friend

Myrtle Beach 2008

Feb. 24th, 2008 | 11:36 pm

http://bojordan.com/log/?p=562

We had a nice crew going to Myrtle Beach this year. The two Pauls were shooting to push Dougherty below his 3:16 needed for Boston, Susi was pacing Jeri in her first race back from her ankle injury, and I was finally trying to break 3 hours.

Jeri and Susi ran a comfortable half, Jeri’s injury thankfully a thing of the past. Being the great supporters they are, I could hear them yelling as I finished right on target in 2:57:40 (top 20!). The last six miles were brutal, the long straightaways of this race a terrible mental test.

Bo finishing

In maximum dramatic form, Dougherty finished with three seconds to spare (3:15:56), with Martino not far behind in a season-best 3:19:37.

pic_0205_450.png

We all earned our post-race massages (great free massage tent), and I even had my first beer of 2008.

Beer tent

I’m not very fond of Myrtle Beach itself, and the race is too straight and flat to be enjoyable to me, but the crowd was great and the whole atmosphere was nice for a mid-sized race.

Link | Leave a comment | Add to Memories | Tell a Friend

Uwharrie 2008

Feb. 10th, 2008 | 02:50 pm

http://bojordan.com/log/?p=559

I had a wonderful time at the Uwharrie Mountain Run last weekend. The race is very well organized, with good coordination at the start and finish and great support along the course. Very highly recommended.


Showing off 20-miler finisher pottery

I ran the 20 miler as my final long run before a fast attempt at Myrtle Beach next weekend, and was able to avoid any major injuries despite the tricky footing (wet feet, minor blisters, and very sore climbing muscles don’t count). While I tried to remain very conservative and not race (I started mid-pack and cautiously stayed behind traffic for most of the first 8 miles), I was happy I ran every hill except the first. I still finished in 3:28 and some change, good enough for 18th overall. I want to return next year and race it.

Susi deserves congratulations; she finished a very respectable 18th female in her first long trail race. Jeri, out with a big ankle sprain, was great to have there in support.

More photos behind the cut )

Link | Leave a comment | Add to Memories | Tell a Friend

Regarding my running log

Feb. 3rd, 2008 | 06:27 pm

http://bojordan.com/log/?p=552

One of my intentions for 2008 was to keep a more diligent log of my exercise. So far, I’m succeeding, and it’s already helping. I suspect most readers of this don’t much care about the daily details of training, so I’ve moved the updates to pages that won’t spill over into the blog. January is here, February here. Feed subscribers rejoice, all three of you.

Why log training activity? This may sound crazy, but my mental window of focus is only a few days wide, and glancing at the past few weeks of training work helps a little in regaining confidence. When I’m not having any trouble with focus or motivation (not-coincidentally, this is usually when I’m mostly group training, but that’s worthy of its own discussion) a training log is little more than a bragging point, and can help a little with a final psyche-up for a big race effort. A daily log is more useful, however, when I’m almost completely distracted, and daily motivation is at a low. Like right now. My past few weeks have been very light, with my ability to get up and motivated in the morning very difficult, due to a mix of some late nights I’ve been putting in and a bit of injury. Due to weekend long runs I’ve still kept overall mileage up around 40 or so, but I don’t feel like I’m doing anything. Why not? I honestly can’t remember what I did just last week unless I write it down, and I get depressed very quickly, panicked that my training base is slipping away.

Are you having trouble staying motivated after setting yet another yearly goal of losing some weight, getting in shape, or just sticking to a plan? Maybe a secret to accomplishing these goals is keeping daily logs.

Link | Leave a comment | Add to Memories | Tell a Friend

It’s Chrimmistime!

Jan. 25th, 2008 | 02:28 am

http://bojordan.com/log/?p=550

This week has been a devastating one for AAPL stock, but undaunted by financial realities I am now awaiting the arrival of a new Mac Pro workstation. Seems like forever ago I began my wait for this hardware refresh so I could replace my aging PowerBook 17. Minorly awesome were upgrade prices for Photoshop and Logic that were less than devastating. Unfortunately playtime is postponed until next month, delays resulting from inclusion of the sweet Nvidia 8800GT graphics. The new apartment heater will be installed as late as the end of February.

Link | Leave a comment | Add to Memories | Tell a Friend