Boost logo

Boost :

From: Noah Stein (noah_at_[hidden])
Date: 2005-10-12 17:20:41


> Deane Yang wrote:
>
> An explanation of affine spaces and their role in computer graphics can
> be found at
>
> http://www.cs.fit.edu/~wds/classes/graphics/Transform/transform/transform.
> html
>
> When working with units and dimensions, we're just doing 1-dimensional
> geometry.
>

I agree completely that we're talking about a 1-dimensional geometry. I
think the issue that people are arguing is, "What space are we using?" For
some, like you and Matt Calabrese, the answer is an affine space.
Unfortunately, affine spaces don't directly support point combinations, so
you create a function that has no meaning in your chosen space.

Others, such as I, view the natural geometry to be a Grassmann space which
supports the addition and scalar weighting of points. Addition of points is
a natural and proper operation. Unfortunately, the best discussion I've
seen requires access to the ACM Digital Library:
http://portal.acm.org/citation.cfm?id=504792 .

The most important question comes down to safety & interface. I myself am
not attracted to choosing a representation and then specifically breaking
the rules of that representation. I also don't like the the idea of seeing
N average functions:

    p=average(p1, p2);
    p=average(p1, p2, p3);
    p=average(p1, p2, p3, p4);

And N barycentric combination functions:

    p=barycentric_combination(w1, p1, w2, p2);
    p=barycentric_combination(w1, p1, w2, p2, w3, p3);
    p=barycentric_combination(w1, p1, w2, p2, w3, p3, w4, p4);

I don't like having two sets of N functions to handle something that is
natural in another space. I, too, like the safety of affine space keeping a
strong separation between points and vectors. Most of my code has a strong
discrimination between the two. I think you can keep that without
destroying the expressivity that others want. To me, I would like to see a
new type added - grassman_point. Add the following functions to create
them:

    grassman_point operator+(point, point);
    grassman_point operator*(scalar, point);
    grassman_point operator*(point, scalar);
    grassman_point operator/(point, scalar);

And then you could combine points as in the following examples (p is a
point, not a grassman_point):

    p=(p1+p2+p3+p4)/4;
    p=0.25*p1+0.25*p2+0.25*p3+0.25*p4;
    p=p1+p2+p3+p4;

In a Grassman space, all of the above result in the same value. Grassman
space is represented with the same homogeneous vector as is used frequently
in computer graphics. Using the usual representation of (v,0) and (p,1),
the points are projected to from (p,w) to (p/w,1) before p is stored back in
the affine point. Thus the third equation is the same as the first.

For safety's sake, you could require an explicit conversion instead of an
implicit one to avoid accidentally performing unwanted point manipulations,
the very reason for choosing an affine space over a simpler vector space.
Thus it would look something like:

    p=combination(0.3*p1+0.25*p2+0.45*p3);

Now, there's only one combination function instead of 2*N functions, and
there's no arbitrary limit to the number of terms. It's rather safe from
unintended point manipulation since, without a specific statement of intent,
it will cause a compiler error. In addition, you could enforce that no
projection occurs and thus the w term already be at 1. This would have the
disadvantage of disallowing a simple average without resorting to a second
class that handles weighting.

-- Noah


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk