Boost logo

Boost :

From: Janek Kozicki (janek_listy_at_[hidden])
Date: 2006-03-20 05:04:53


> I've put a zip containing some 2D/3D geometry primitives in the Math - Geometry
> directory:
>
> http://tinyurl.com/mbaol
>
> No docs or tests. Developed using VC7.1. Needs Boost.Typeof which is only
> available in CVS. The two rc_transform.hpp headers currently also have
> dependencies on an external angle type so wont compile (unless you download the
> original pqs http://tinyurl.com/s7hu6) , however I am working to make a set of
> angle types available as part of my proposed Boost Pqs library:
> http://tinyurl.com/7m5l8

Hi,

I will try to help you with that geometry library, because I want to
use boost too, instead of dragging everywhere similar library
(with quaternions, and all that 3D stuff). I'm mainly using that library
for discrete simulation modelling (shameless plug: http://yade.berlios.de/ ).
So I'm comparing your work against mine :)

1. in file vect_def.hpp you have default constructor:

        vect()
        : x( static_cast<T>(0) )
        , y( static_cast<T>(0) )
        , z( static_cast<T>(0) )
        {}

IMHO it's better to leave values uninitialized, if anyone needs to
initialize to anything, he will call the second constructor. Also
leaving variable uninitialized when no initialization value is given is
the standard behaviour. boost::numeric::ublas leaves vectors
uninitialized too. Think about performance when constructing a big array
(that will be initialized by the user just after it's constructed...)

2. in file vect.hpp, function magnitude( vect<Value_type> const & v), I
think you should add std:: there

Value_type result = std::sqrt(v.x * v.x + v.y * v.y + v.z * v.z);

Personally I prefer name "length" because it is shorter to type than
"magnitude", but naming is not that important ;)

3. speaking of length, a function that returns squared length is very
useful too, because it is faster. And people often use squared length when
they just compare to get something longer (or shorter) but don't
care about the actual length.

4. How about negation? it's operator-(T), it negates the argument.
I'm typing this code without actual checking, but you should understand
what I mean:

    template <typename TR>
    inline
    vect <BOOST_TYPEOF_TPL(TR())>
    operator -( vect<TR> const & rhs)
    {
        return result(-rhs.x,-rhs.y,-rhs.z);
    }

5. how about operator-=() ; operator+=() ; operator*=() ; operator/=() ?

6. maybe I don't understand something here, but why do you always
declare temporary variable "result" just to return it one line later? Is
it necessery for type checking? (function already has declared it's
return type).

7. normalize() function is useful, it normalizes the vector and returns its length:
(I'm also quick-typing this here):

    template <typename T>
    BOOST_TYPEOF_TPL( T() )
    normalize(
        vect<T>& vec
    ){
        typedef BOOST_TYPEOF_TPL( T() ) length_type;
        length_type length=magnitude(vec);
        vec.x/=length;
        vec.y/=length;
        vec.z/=length;
        return length;
    }

8. when working with volumes it is useful to quickly find encompassing
volume by performing scalar_max() on all volumes in question:

    template <typename T>
    vect<BOOST_TYPEOF_TPL( T() )>
    scalar_max(
        const vect<T>& lhs,
        const vect<T>& rhs
    ){
        return vect<BOOST_TYPEOF_TPL( T() )>(
            std::max(lhs.x , rhs.x),
            std::max(lhs.y , rhs.y),
            std::max(lhs.z , rhs.z)
        );
    }

9. scalar_min() can be sometimes useful too, and to be complete both
functions should be added, I think...

10. what is that semicolon at the end of line 107 in vect.hpp? ;)), that '-' in
line 106 looks suspicious too ;)

11. unit_cross_product() is useful in openGL, it's just like
cross_product, but the result is normalized:

    template<typename T>
    vect<BOOST_TYPEOF_TPL( T() * T())>
    unit_cross_product(
        const vect<T>& lhs,
        const vect<T>& rhs
    ){
        vect<BOOST_TYPEOF_TPL( T() * T())> result(
            lhs.y * rhs.z - lhs.z * rhs.y,
            lhs.z * rhs.x - lhs.x * rhs.z,
            lhs.x * rhs.y - lhs.y * rhs.x
        );
        normalize(result);
        return result;
    }

12. we have a dot product and cross product, but how about diagonal
multiplication of two vectors?

    template<typename T>
    vect<BOOST_TYPEOF_TPL( T() * T())>
    mult_diagonal(
        vect<T> const & lhs,
        vect<T> const & rhs
    ){
        return vect<BOOST_TYPEOF_TPL( T() * T())>(
            lhs.x * rhs.x,
            lhs.y * rhs.y,
            lhs.z * rhs.z
        );
    }

looks like that's all for now :) In your previous post you mentioned
quaternions, but I don't see quaternions in this geometryAL_01.zip file.
I'm not using matrices to rotate in my code, but quaternions, so (for
now) I don't have suggestions about rc_matrix. I'm only curious why the
"rc_" prefix to the name? I'm looking forward to see quaternions.hpp :))

I'll try to switch my program (yade is over 30000 lines of C++ ;) into
this library, as a part of helping in getting this library done. So I
will be able to perform numreous benchmarks and unit tests to compare
both libraries (both compuational correctness and speed).

-- 
Janek Kozicki                                                         |

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