Polygon Triangulation With Hole

2022.05.20   prev     next

THIS is a quick tutorial on dividing a polygon into triangles. If you need a code sample, visit the non-blog version of this tutorial, then choose Develop > Show Page Source (or equivalent) in your web browser to see the JavaScript section at the bottom. (It is public domain! 😀)

 

A GPU draws triangles, and it draws them very quickly.

 

But it won’t draw more complex polygons, like quadrilaterals, pentagons, hexagons, etc. So if you want to use a GPU to draw any polygon other than a triangle,

 

you’ll need to break that polygon into multiple triangles, then pass these triangles to the GPU for drawing.

 

The GPU will seamlessly fill the triangles, leaving no visible evidence that the polygon was actually drawn as a set of triangles.

 

If your polygon is convex, then the task of turning it into triangles is trivial: Just pick any corner, and connect it to every other corner (to which it isn’t already connected). Done.

 

But if your polygon is concave, it’s not that simple. Such connectors might go outside the polygon, creating triangles that will cause the GPU to fill pixels outside the desired area.

What we need is an algorithm that will consistently break up a polygon — even a very concave, possibly convoluted one — into triangles. For optimal GPU handling, we would prefer that it generate as few triangles as possible. It turns out that the minimum number of triangles is always n-2, where n is the number of corners of the polygon. So if we have a twenty-cornered polygon, it can always be broken up into eighteen triangles. And incidentally, all of those triangles will use corners of the original polygon as their corners; none of triangle’s corners will be points in the interior of the original polygon, nor along any of the original polygon’s sides.

 

Is it sometimes possible to break up a polygon into fewer than n-2 triangles? Yes, it is. For example, here’s a five-pointed star, which is a ten-cornered polygon. It can be rendered as eight triangles, as depicted above.

 

But it could be drawn as just four triangles, like this.

However, there’s an important reason not to do that, and we’ll talk about it a bit later. For now, just be aware that our algorithm is going to make n-2 triangles, every time.

 

Question: Is it always possible to break up a concave polygon into n-2 triangles, using only corners of the original polygon? And if it is, is it guaranteed that the algorithm described in this presentation will always find such a solution? Yes, and yes. However, we’re not going to get into the proof of that here. Just trust me, it will always work.

 

It will work, that is, if the polygon is well-behaved. That means: (1) The polygon has at least three corners (duh) with no consecutive corners identical on both coordinates, (2) the polygon is traced clockwise, and (3) the polygon doesn’t cross itself.

You might be wondering: Why clockwise? What difference does it make? Isn’t that just an arbitrary direction? And what does clockwise mean, anyway? Doesn’t that depend on your coordinate system? Does your Y coordinate ascend from the bottom up, or from the top down, and doesn’t that affect the meaning of clockwise?

Yes, that’s all correct. What this requirement really says is: Decide what clockwise means in your system, then stick with that decision. It does matter, because if you trace the polygon in the wrong direction, then this algorithm is going to try to triangulate the area outside your polygon, which won’t work, and it’s not what you wanted anyway.

The polygon can’t cross itself, but can it touch itself? The answer is: maybe.

If it touches itself with shared corners, like this,

or fully shared sides, like this,

that’s OK. (In fact, we’re going to be using that technique later when we talk about holes.)

But — if it touches itself corner-to-side, like this,

or partial-side-to-side, like this,

that may not be OK. There’s an infinitely fine line between touching and crossing, and even if the touches are mathematically exactly correct, they still might fail our algorithm. So don’t do that.

 

Our algorithm is going to deliver a list of triangles (not a triangle strip, if you know what that is). The triangles won’t necessarily be in any particular order, but they will fit together to perfectly cover the original polygon, and they won’t overlap each other at all. They also won’t cover any area outside of the polygon.

Furthermore, all the triangles will be traced clockwise. That might not mean anything to your GPU — or, it might be necessary to ensure that the triangles fit together, filling all pixels without visible seams.

 

The algorithm itself is quite simple: Crawl around the edge of the polygon, examining every set of three consecutive corners until you find three that make a good candidate triangle. A good triangle (1) will be inside the polygon, not outside, meaning that the three corners must not represent a locally counterclockwise bend, and (2) will not contain any existing corners of the polygon in the triangular interior.

 

This candidate triangle is rejected, because it represents a locally counterclockwise bend, and therefore is on the outside of the polygon.

 

This candidate triangle also is rejected, because it includes a corner of the polygon in its interior space.

 

This candidate triangle is accepted. So we add these three corners, in this order (which is clockwise) to our list of triangles.

 

Then we remove the middle corner (of the accepted triangle) from our working polygon, which exactly removes the accepted triangle’s ar­e­a from the polygon.

 

Then we go back and do it again. The polygon gets smaller and smaller as triangles are added to the list. When the polygon is reduced to just two corners, the process is done, and the triangle list is complete.

 

Question: Is it OK if three corners line up perfectly and make a zero-area triangle? In this example, a ten-cornered (and totally well-behaved) polygon is broken up into eight triangles. It looks like there are only seven triangles, but there is a zero-area triangle (denoted by the red dots) sandwiched between the upper four triangles and the lower three triangles. Answer: Yes that is very much OK. In fact, that zero-area triangle should be kept and used — don’t discard it! Why not? Right now, these three points are exactly collinear, but by the time the GPU is drawing these triangles, tiny rounding errors might cause these three points to be slightly noncollinear. The triangle list is going to go through various transformations: scaling to adjust size, possibly a rotation, or a skew, or a perspectivization. When it’s all over, there’s no guarantee that these three points will be perfectly, mathematically collinear.

 

And if they’re not, then omitting that triangle might cause a tiny gap between the upper four and lower three triangles. That gap could be visible to the user as a light scattering of unfilled pixels. Yuck!

 

Can our algorithm go into an infinite loop, crawling around the polygon and never finding an acceptable triangle? No, not if the polygon data is well-behaved, as we talked about earlier. But because the polygon data might be ill-behaved, our code should be structured so that, if it examines all corner triplets without finding an acceptable triangle, it will exit with a failure message, and not go into an infinite loop.

 

So, let’s watch the algorithm in action. Here’s a well-behaved polygon. It has seven corners, and coincidentally is shaped like the number seven.

 

Now the algorithm triangulates it.

(These images are generated from actual code; see the live animation in the non-blog version of this page. The JavaScript source code within that page itself can be viewed by choosing Develop > Show Page Source, or equivalent, in your web browser.)

 

Done! The seven-cornered polygon turned into five triangles, as expected.

 

Did you notice something strange at the end there? Let’s go back two triangles and take a look.

Hey, it sure looks like we’ve only got one triangle left. But it made two triangles. Why did it do that? Of course, the reason is because the algorithm isn’t smart enough to see that it could have made one triangle. So should we modify it to detect this condition and make one triangle? No, we should not. Why not?

 

Notice that all of these triangles interface with each other by full sides. This triangle shares a full side with this one.

 

This one shares a full side with this one.

 

If we make this remaining (grey) area into a single triangle, then it will interface with the triangle below by less than a full side. That could cause the missing-pixels problem we discussed earlier in the zero-area-triangle situation.

So it’s best just to let the algorithm do its thing, generating exactly n-2 triangles every time.

 

Now let’s explore the possibility of a polygon with a hole.

 

If you just want the hole to contain a different color (or fill-pattern) than does the rest of the polygon, you can simply render the outside polygon first,

 

then render the hole polygon over it.

That works, but it does require the GPU to fill all the pixels in the hole’s area twice, first with yellow (in this example), then again with red. It also requires the GPU to render the yellow triangles first, then the red ones — instead of letting it render all of this object’s triangles in whatever order it finds most efficient.

 

But the biggest reason not to do it that way is that you might actually want a true hole in the polygon, not just a different fill. A true hole will allow whatever has already been drawn to show through the hole.

 

So how do we do it? First, check every connection between any corner of the outer polygon, and any corner of the hole polygon, keeping only the shortest one you find.

The connector must not cross any side of either polygon, so this one would be invalid.

 

Here’s why you want the shortest connector: This connector might not be considered to cross any side of either polygon,

 

but to avoid unnecessary potential problems, it would be better to use this one instead. It will always be shorter, so using the shortest connector will avoid such problems.

 

Here is the shortest valid connector in our example. When you find it,

 

then turn the two polygons into one, big polygon, that traces clockwise around the outside, goes in on the connector, then traces the hole polygon in reverse, and comes back out on the connector.

Now we have a single polygon, traced clockwise overall, and which does not cross itself (although it does have some duplicate corners at the connector; that’s OK). Simply apply the algorithm we already have discussed, and the polygon will be triangulated, with the hole left open.

 

Here’s an example: The number six. It has a big hole in the middle.

 

Triangulating...

 

Done!

 

One final note: What if a polygon has three consecutive corners that are collinear, like this one does? Should you keep those corners, to prevent missing pixels? No, actually, as long as this condition exists in your original polygon, you can safely remove the middle corner. (In fact, the three corners don’t even have to be perfectly collinear: You decide how close to collinear they need to be, and remove the middle corner if you think it won’t hurt the appearance of your polygon.)

Why is that OK? Because we haven’t even started the triangulation yet. Any modifications to the original polygon are perfectly fine, as long as it’s still a well-behaved polygon when you start the triangulating procedure.

And that’s about it for now! I hope it was informative, and please don’t be shy about contacting me if you spot a mistake or have an interesting insight. 😀

prev     next

 

 

Hear, hear

prev     next

Best recent articles

Make Your Own FBI Backdoor, Right Now

Polygon Triangulation With Hole

The Legacy of Windows Phone

Palm Fan

Vivek Wadhwa, Scamster Bitcoin Doomsayer

Fanboy Features (regularly updated)

When Starting A Game of Chicken With Apple, Expect To Lose — hilarious history of people who thought they could bluff Apple into doing whatever they wanted.

A Memory of Gateway — news chronology of Apple’s ascendancy to the top of the technology mountain.

iPhone Party-Poopers Redux and Silly iPad Spoilsports — amusing litanies of industry pundits desperately hoping iPhone and iPad will go away and die.

Embittered Anti-Apple Belligerents — general anger at Apple’s gi-normous success.

RSS FEED

My books

Now available on Apple Books!

   

Links

Daring Fireball

The Loop

RoughlyDrafted

Macalope

Red Meat

Despair, Inc.

Real Solution #9 (Mambo Mania Mix) over stock nuke tests. (OK, somebody made them rip out the music — try this instead.)

Ernie & Bert In Casino

Great Explanation of Star Wars

Best commercials (IMO) from Super Bowl 41, 43, 45, 46, 47, 53 and 55

Kirk & Spock get Closer

American football explained.

TV: Succession; Better Call Saul; Homeland; Survivor; The Jinx; Breaking Bad; Inside Amy Schumer

God’s kitchen

Celebrity Death Beeper — news you can use.

Making things for the web.

RedQueenCoder.

My vote for best commercial ever. (But this one’s a close second, and I love this one too.)

Recent commercials I admire: KFC, Audi, Volvo

Best reggae song I’ve discovered in quite a while: Virgin Islands Nice

d120 dice: You too (like me) can be the ultimate dice nerd.

WiFi problems? I didn’t know just how bad my WiFi was until I got eero.

Favorite local pad thai: Pho Asian Noodle on Lane Ave. Yes, that place; blame Taco Bell for the amenities. Use the lime, chopsticks, and sriracha. Yummm.

Um, could there something wrong with me if I like this? Or this?

This entire site as a zip file — last updated 2023.10.06

Previous articles

Engström’s Motive

Google’s Decision

Warrening

The Two Envelopes Problem, Solved

The Practical Smartphone Buyer

Would Apple Actually Exit the EU Or UK?

See You Looked

Blackjack Strategy Card (Printable)

Swan Device 1956 — Probable Shape

Pu

RGB-To-Hue Conversion

Polygon Triangulation With Hole

One-Point Implosion: “Palm Fan”

Implosion: Were Those Two-Speed Lenses Really Necessary?

Apple Wants User/Developer Choice; Its Enemies Want Apple Ruin

Tim Sweeney Plays Dumb

The Jury of One

The Lesson of January 6

Amnesia Is Not A Good Plot

I Was Eating for 300 lbs, Not 220

Action Arcade Sounds and Reality

The Flea Market and the Retail Store

Squaring the Impossible

Yes, Crocodiles Are Dinosaurs — Duh

Broccoli and Apples Are Not the Antidote To Donuts and Potato Chips

Cydia and “Competition”

The Gift of Nukes

Prager University and the Anti-Socialists’ Big Blind Spot

In Defense of Apple’s 30% Markup, Part 2

In Defense of Apple’s 30% Markup

Make Your Own FBI Backdoor, Right Now

Storm

The Legacy of Windows Phone

Mindless Monsters

To the Bitter End

“Future Shock” Shock

Little Plutonium Boy

The iPhone Backdoor Already Exists

The Impulse To Be Lazy

HBO’s “Meth Storm” BS

Judos vs. Pin Place

Vizio M-Series 65" LCD (“LED”) TV — Best Settings (IMHO)

Tasting Vegemite (Bucket List)

The IHOP Coast

The Surprise Quiz Paradox, Solved

Apple, Amazon, Products, and Services — Not Even Close

Nader’s Open Blather

Health — All Or Nothing?

Vivek Wadhwa, Scamster Bitcoin Doomsayer

Backwards Eye Wiring — the Optical Focus Hypothesis

Apple’s Cash Is Not the Key

Nothing More Angry Than A Cornered Anti-Apple

Let ’Em Glow

The Ultimate, Simple, Fair Tax

Compassion and Vision

When Starting A Game of Chicken With Apple, Expect To Lose

The Caveat

Superb Owl

NavStar

Basic Reproduction Number

iBook Price-Fixing Lawsuit Redux — Apple Won

Delusion Made By Google

Religion Is A Wall

It’s Not A Criticism, It’s A Fact

Michigan Wolverines 2014 Football Season In Review

Sprinkler Shopping

Why There’s No MagSafe On the New MacBook

Sundar Pichai Says Devices Will Fade Away

The Question Every Apple Naysayer Must Answer

Apple’s Move To TSMC Is Fine For Apple, Bad For Samsung

Method of Implementing A Secure Backdoor In Mobile Devices

How I Clip My Cat’s Nails

Die Trying

Merger Hindsight

Human Life Decades

Fire and the Wheel — Not Good Examples of A Broken Patent System

Nobody Wants Public Transportation

Seasons By Temperature, Not Solstice

Ode To Coffee

Starting Over

FaceBook Messenger — Why I Don’t Use It

Happy Birthday, Anton Leeuwenhoek

Standard Deviation Defined

Not Hypocrisy

Simple Guide To Progress Bar Correctness

A Secure Backdoor Is Feasible

Don’t Blink

Predictive Value

Answering the Toughest Question About Disruption Theory

SSD TRIM Command In A Nutshell

The Enderle Grope

Aha! A New Way To Screw Apple

Champagne, By Any Other Maker

iOS Jailbreaking — A Perhaps-Biased Assessment

Embittered Anti-Apple Belligerents

Before 2001, After 2001

What A Difference Six Years Doesn’t Make

Stupefying New Year’s Stupidity

The Innovator’s Victory

The Cult of Free

Fitness — The Ultimate Transparency

Millions of Strange Devotees and Fanatics

Remember the iPod Killers?

Theory As Simulation

Four Analysts

What Was Christensen Thinking?

The Grass Is Always Greener — Viewing Angle

Is Using Your Own Patent Still Allowed?

The Upside-Down Tech Future

Motive of the Anti-Apple Pundit

Cheating Like A Human

Disremembering Microsoft

Security-Through-Obscurity Redux — The Best of Both Worlds

iPhone 2013 Score Card

Dominant and Recessive Traits, Demystified

Yes, You Do Have To Be the Best

The United States of Texas

Vertical Disintegration

He’s No Jobs — Fire Him

A Players

McEnroe, Not Borg, Had Class

Conflict Fades Away

Four-Color Theorem Analysis — Rules To Limit the Problem

The Unusual Monopolist

Reasonable Projection

Five Times What They Paid For It

Bypassable Security Certificates Are Useless

I’d Give My Right Arm To Go To Mars

Free Advice About Apple’s iOS App Store Guidelines

Inciting Violence

One Platform

Understanding IDC’s Tablet Market Share Graph

I Vote Socialist Because...

That Person

Product Naming — Google Is the Other Microsoft

Antecessor Hypotheticum

Apple Paves the Way For Apple

Why — A Poem

App Anger — the Supersized-Mastodon-In-the-Room That Marco Arment Doesn’t See

Apple’s Graphic Failure

Why Microsoft Copies Apple (and Google)

Coders Code, Bosses Boss

Droidfood For Thought

Investment Is Not A Sure Thing

Exercise is Two Thirds of Everything

Dan “Real Enderle” Lyons

Fairness

Ignoring the iPod touch

Manual Intervention Should Never Make A Computer Faster

Predictions ’13

Paperless

Zeroth — Why the Century Number Is One More Than the Year Number

Longer Than It Seems

Partners: Believe In Apple

Gun Control: Best Arguments

John C. Dvorak — Translation To English

Destructive Youth

Wiens’s Whine

Free Will — The Grand Equivocation

What Windows-vs.-Mac Actually Proved

A Tale of Two Logos

Microsoft’s Three Paths

Amazon Won’t Be A Big Winner In the DOJ’s Price-Fixing Suit

Infinite Sets, Infinite Authority

Strategy Analytics and Long Term Accountability

The Third Stage of Computing

Why 1 Isn’t Prime, 2 Is Prime, and 2 Is the Only Even Prime

Readability BS

Lie Detection and Psychos

Liking

Steps

Microsoft’s Dim Prospects

Humanity — Just Barely

Hanke-Henry Calendar Won’t Be Adopted

Collatz Conjecture Analysis (But No Proof; Sorry)

Rock-Solid iOS App Stability

Microsoft’s Uncreative Character

Microsoft’s Alternate Reality Bubble

Microsoft’s Three Ruts

Society’s Fascination With Mass Murder

PlaysForSure and Wikipedia — Revisionism At Its Finest

Procrastination

Patent Reform?

How Many Licks

Microsoft’s Incredible Run

Voting Socialist

Darwin Saves

The Size of Things In the Universe

The Self-Fulfilling Prophecy That Wasn’t

Fun

Nobody Was In Love With Windows

Apples To Apples — How Anti-Apple Pundits Shoot Themselves In the Foot

No Holds Barred

Betting Against Humanity

Apple’s Premium Features Are Free

Why So Many Computer Guys Hate Apple

3D TV With No Glasses and No Parallax/Focus Issues

Waves With Particle-Like Properties

Gridlock Is Just Fine

Sex Is A Fantasy

Major Player

Why the iPad Wannabes Will Definitely Flop

Predators and Parasites

Prison Is For Lotto Losers

The False Dichotomy

Wait and See — Windows-vs-Mac Will Repeat Itself

Dishonesty For the Greater Good

Barr Part 2

Enough Information

Zune Is For Apple Haters

Good Open, Bad Open

Beach Bodies — Who’s Really Shallow?

Upgrade? Maybe Not

Eliminating the Impossible

Selfish Desires

Farewell, Pirate Cachet

The Two Risk-Takers

Number of Companies — the Idiocy That Never Dies

Holding On To the Solution

Apple Religion

Long-Term Planning

What You Have To Give Up

The End of Elitism

Good and Evil

Life

How Religion Distorts Science

Laziness and Creativity

Sideloading and the Supersized-Mastodon-In-the-Room That Snell Doesn’t See

Long-Term Self-Delusion

App Store Success Won’t Translate To Books, Movies, and Shows

Silly iPad Spoilsports

I Disagree

Five Rational Counterarguments

Majority Report

Simply Unjust

Zooman Science

Reaganomics — Like A Diet — Works

Free R&D?

Apple’s On the Right Track

Mountains of Evidence

What We Do

Hope Conquers All

Humans Are Special — Just Not That Special

Life = Survival of the Fittest

Excuse Me, We’re Going To Build On Your Property

No Trademark iWorries

Knowing

Twisted Excuses

The Fall of Google

Real Painters

The Meaning of Kicking Ass

How To Really Stop Casual Movie Disc Ripping

The Solitary Path of the High-Talent Programmer

Fixing, Not Preaching

Why Blackmail Is Still Illegal

Designers Cannot Do Anything Imaginable

Wise Dr. Drew

Rats In A Too-Small Cage

Coming To Reason

Everything Isn’t Moving To the Web

Pragmatics, Not Rights

Grey Zone

Methodologically Dogmatic

The Purpose of Language

The Punishment Defines the Crime

Two Many Cooks

Pragmatism

One Last Splurge

Making Money

What Heaven and Hell Are Really About

America — The Last Suburb

Hoarding

What the Cloud Isn’t For

Diminishing Returns

What You’re Seeing

What My Life Needs To Be

Taking An Early Retirement

Office Buildings

A, B, C, D, Pointless Relativity

Stephen Meyer and Michael Medved — Where Is ID Going?

If You Didn’t Vote — Complain Away

iPhone Party-Poopers Redux

What Free Will Is Really About

Spectacularly Well

Pointless Wrappers

PTED — The P Is Silent

Out of Sync

Stupid Stickers

Security Through Normalcy

The Case For Corporate Bonuses

Movie Copyrights Are Forever

Permitted By Whom?

Quantum Cognition and Other Hogwash

The Problem With Message Theory

Bell’s Boring Inequality and the Insanity of the Gaps

Paying the Rent At the 6 Park Avenue Apartments

Primary + Reviewer — An Alternative IT Plan For Corporations

Yes Yes Yes

Feelings

Hey Hey Whine Whine

Microsoft About Microsoft Visual Microsoft Studio Microsoft

Hidden Purple Tiger

Forest Fair Mall and the Second Lamborghini

Intelligent Design — The Straight Dope

Maxwell’s Demon — Three Real-World Examples

Zealots

Entitlement BS

Agenderle

Mutations

Einstein’s Error — The Confusion of Laws With Their Effects

The Museum Is the Art

Polly Sooth the Air Rage

The Truth

The Darkness

Morality = STDs?

Fulfilling the Moral Duty To Disdain

MustWinForSure

Choice

Real Design

The Two Rules of Great Programming

Cynicism

The End of the Nerds

Poverty — Humanity’s Damage Control

Berners-Lee’s Rating System = Google

The Secret Anti-MP3 Trick In “Independent Women” and “You Sang To Me”

ID and the Large Hadron Collider Scare

Not A Bluff

The Fall of Microsoft

Life Sucks When You’re Not Winning

Aware

The Old-Fashioned Way

The Old People Who Pop Into Existence

Theodicy — A Big Stack of Papers

The Designed, Cause-and-Effect Brain

Mosaics

IC Counterarguments

The Capitalist’s Imaginary Line

Education Isn’t Everything

I Don’t Know

Funny iPhone Party-Poopers

Avoiding Conflict At All Costs

Behavior and Free Will, Unconfused

“Reduced To” Absurdum

Suzie and Bubba Redneck — the Carriers of Intelligence

Everything You Need To Know About Haldane’s Dilemma

Darwin + Hitler = Baloney

Meta-ware

Designed For Combat

Speed Racer R Us

Bold — Uh-huh

Conscious of Consciousness

Future Perfect

Where Real and Yahoo Went Wrong

The Purpose of Surface

Eradicating Religion Won’t Eradicate War

Documentation Overkill

A Tale of Two Movies

The Changing Face of Sam Adams

Dinesh D’Souza On ID

Why Quintic (and Higher) Polynomials Have No Algebraic Solution

Translation of Paul Graham’s Footnote To Plain English

What Happened To Moore’s Law?

Goldston On ID

The End of Martial Law

The Two Faces of Evolution

A Fine Recommendation

Free Will and Population Statistics

Dennett/D’Souza Debate — D’Souza

Dennett/D’Souza Debate — Dennett

The Non-Euclidean Geometry That Wasn’t There

Defective Attitude Towards Suburbia

The Twin Deficit Phantoms

Sleep Sync and Vertical Hold

More FUD In Your Eye

The Myth of Rubbernecking

Keeping Intelligent Design Honest

Failure of the Amiga — Not Just Mismanagement

Maxwell’s Silver Hammer = Be My Honey Do?

End Unsecured Debt

The Digits of Pi Cannot Be Sequentially Generated By A Computer Program

Faster Is Better

Goals Can’t Be Avoided

Propped-Up Products

Ignoring ID Won’t Work

The Crabs and the Bucket

Communism As A Side Effect of the Transition To Capitalism

Google and Wikipedia, Revisited

National Geographic’s Obesity BS

Cavemen

Theodicy Is For Losers

Seattle Redux

Quitting

Living Well

A Memory of Gateway

Is Apple’s Font Rendering Really Non-Pixel-Aware?

Humans Are Complexity, Not Choice

A Subtle Shift

Moralism — The Emperor’s New Success

Code Is Our Friend

The Edge of Religion

The Dark Side of Pixel-Aware Font Rendering

The Futility of DVD Encryption

ID Isn’t About Size or Speed

Blood-Curdling Screams

ID Venn Diagram

Rich and Good-Looking? Why Libertarianism Goes Nowhere

FUV — Fear, Uncertainty, and Vista

Malware Isn’t About Total Control

Howard = Second Coming?

Doomsday? Or Just Another Sunday

The Real Function of Wikipedia In A Google World

Objective-C Philosophy

Clarity From Cisco

2007 Macworld Keynote Prediction

FUZ — Fear, Uncertainty, and Zune

No Fear — The Most Important Thing About Intelligent Design

How About A Rational Theodicy

Napster and the Subscription Model

Intelligent Design — Introduction

The One Feature I Want To See In Apple’s Safari.