Skip to content

When Is a Point Not Necessarily a Point?

ADMIN | 27-01-2012

When Is a Point Not Necessarily a Point?

Hexagon pattern 1

Answer: when it’s a 'HappyPathPoint'.

Happy New Year everyone! I left off my last post with a dilemma: I wanted to design the interface for a function that people will call when they want to find the closest point on a surface to a test point. The problem is that the answer to this question is only usually a single, isolated point. Every now and then the answer is a set of (more than one) points. For example, all the points on a spherical surface are 'closest' to its center. So how does one design the interface so that the person writing the client code naturally accounts for this subtlety, while not forcing him to deal with an awkward interface?

I already stated that the wrong thing to do is to simply document the subtlety and hope the customer will notice it. A better solution is to (in addition to documentation) make the name of the function reflect the subtlety: prefer 'FindAClosestPoint' over 'FindClosestPoint'. The problem with this idea is that it doesn’t actually deal with the problem – how is the customer to tell if he’s on the happy path, or has run into the complex condition? And again, it relies on the customer noticing that something is up (rather than having the compiler tell him).

My preferred solution (which we first thought of while working on an ACIS project to make our internal interfaces more robust) is to introduce a new object called a 'HappyPathPoint'; the idea is that the function returns this object rather than a raw point:

happy_point_code1

As you can see, HappyPathPoint encapsulates both possible answers: if IsPoint() returns true, then the answer is (the typical case of) an isolated point and it’s safe for the customer to use the Value() method to get the point. If IsPoint() returns false, however, then the answer is (the extremely rare case of) a more general point set, and the customer should use a different branch in his analysis code:

happy_points_code2

In reality, the customer’s initial implementation for the branch where IsPoint() returns false will simply be to throw an error (and put a project in the backlog to think about what his algorithm should do). This is still a big improvement over the case where the customer’s code ignores the subtlety – what was previously a subtlety is now simply an extra question about the answer, and the code for dealing with the atypical case is isolated at the point where that case is first introduced.

One interesting question in all this is "What should the behavior of Value() be if it is called before IsPoint() has been called?" I see three possibilities:

A) Silently return an arbitrary point in the point set B) In release builds, return an arbitrary point. When contract checks are on, throw. C) Always throw

My preferred answer is B, especially if it is used in conjunction with a code coverage tool that ensures that you test suite will always hit the (invalid) call to Value() (with contract checks turned on, of course). The reason that this works is that the question I asked was NOT "What should the behavior of Value() be if it is called when IsPoint() is false?" That case will only show up in the atypical situations, and so typically won’t be hit in customer testing. The contract is that the customer must validate that the HappyPathPoint truly represents an isolated point before calling Value(), even if the HappyPathPoint happens to be an isolated point. This ensures that the client code is correctly written, even if none of its test cases hit the atypical case.

For those of you who speak C#, you should see similarities with the 'nullable' class that allows one to wrap a value class up into something that can be tested against null. As with nullable, the compiler will warn you if you try to use a HappyPathPoint where a Point is expected. HappyPathPoint is more powerful than nullable, however: nullable doesn’t protect (as a contract check) against an untested call to Value(), and it doesn’t provide an alternative answer.

I hope that I’ve convinced at least someone out there that this is a good idea. I don’t think it’s overly burdensome, and it makes the subtlety obvious in the interface. It is important not to adopt this idea as a one-off, however – if you’re going to use it, it should be implemented uniformly across your interface. The code snippets above are just an example; an interesting thing to try might be to write a HappyPath template class.

The last thing I want to say is that we’ve been thinking about this idea for years, and still don’t have a good name!! Any ideas for a better one? 'PointCandidate' maybe?

 

You might also like...

c138_2_cropped
3 Min read
3D ACIS
We often focus the success of new partners, showcasing how Spatial helped with bringing a new product to market. But...
Large Tolerant  Vertex
3 Min read
3D Software Development Kits
boolean operation Boolean operations on individual bodies are common functions in 3D modeling. While simple in concept,...
3 Min read
3D Software Development Kits
In much the same way as physical design has moved from paper 2D drawings to 3D models in software, so has analysis....
4 Min read
3D InterOp
Part and parcel with model-based engineering is model translation. Because the model is now the specification, accurate...
4 Min read
3D ACIS
We are moving things around in the office here at Spatial to accommodate some new people. As a result, our marketing...
2 Min read
3D ACIS
This article shares a simple architecture which can be used to capture meta-data about the use of ACIS APIs in your...
1 Min read
3D ACIS
How To Create an Ellipsoid using 3D ACIS The 3D analytics supported directly in 3D ACIS include: sphere, block,...
2 Min read
3D ACIS
Basically, there are two priorities when using a software component, particularly a 3D modeling kernel: Does it do what...
1 Min read
3D ACIS
A geometry kernel is a big thing. It’s a huge thing. Maybe even big enough to see from space. By most accounts, even...
1 Min read
3D ACIS
My comrades and I did a performance analysis of Intel’s Hyper Threading Technology (HTT), using thread-safe ACIS and...
3 Min read
3D ACIS
In earlier posts I’ve written a lot about the various approaches to multiprocessing and the potential benefits. What I...
2 Min read
3D ACIS
The challenges of a major software release are not unique to Spatial. And like other organizations, the launch process...
5 Min read
3D ACIS
We’ve known for a long time that the integrity of B-rep data plays a major role in the success of downstream modeling...
3 Min read
3D ACIS
Answer: when it’s a 'HappyPathPoint'.
1 Min read
3D ACIS
To finish up this series of posts; what Gregg's post described happened a few years ago. Since that first team room,...
4 Min read
3D ACIS
This post will discuss two aspects of my favorite programming language, C++:
2 Min read
3D ACIS
Way back in the Dark Ages of the mid-90s, I used to read a newsgroup called comp.lang.c++. You can tell this was the...
7 Min read
3D ACIS
Here’s a subject to which everyone can relate in one way or another: growable arrays. An array is a contiguous memory...