Boost logo

Boost :

From: Andy Little (andy_at_[hidden])
Date: 2006-03-20 09:14:28

> "Janek Kozicki" wrote
>> Andy little wrote
>> I've put a zip containing some 2D/3D geometry primitives in the Math -
>> Geometry
>> directory:
>> 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 , however I am working to make a set
>> of
>> angle types available as part of my proposed Boost Pqs library:
> 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: ).
> So I'm comparing your work against mine :)

Wow. It looks impressive. I note the intention in the schedule; Milestone 4 to
"Use physical units, from dimnum or SIunits library".
What is the status of that? Naturally having spent some time on proposed Boost
Pqs library would be interested to see if it might be
used for this purpose.

> 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...)

OK.. though the rationale is that its occasionally useful to set a variable to a
known state. Without any initialisation a variable can start in a random state,
so theoretically cause occasional non-repeatable bugs.

How about adding a compile time switch (macro) to enable/disable zero
initialisation?. That could also be used to measure the effect of initialisation
on performance too.

> 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);

The intent is to allow the correct sqrt to be selected by ADL. The quantities in
pqs have a sqrt function in boost::pqs namespace. It might be worth adding using
std::sqrt though.

> 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.

Right. Is that the same as what norm(std::complex) does ?

> 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
> operator -( vect<TR> const & rhs)
> {
> return result(-rhs.x,-rhs.y,-rhs.z);
> }

Yes I should add that.

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

Yes I must add those, assuming the argument is an arithmetic type.

> 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).

Its an attempt to get the so-called Named Return Value Optimisation:
(Heres first reference I found on it in quick search)

> 7. normalize() function is useful, it normalizes the vector and returns its
> length:
> (I'm also quick-typing this here):
> template <typename 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;
> }

Ok. Is that useful for rotation axis for instance?

> 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)
> );
> }

Ok. Is that sometimes implemented as a logical operator e.g Or is max and And is
Mind you that may not be comprehensible for vect...

> 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 ;)

Yes they are typos. There need to be some tests!

> 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
> );
> }

Ok. All those should be added..

> looks like that's all for now :) In your previous post you mentioned
> quaternions, but I don't see quaternions in this 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 :))

the rc_ prefix stands for Row-Column format (as opposed to Column-Row format).
It might be best to use the OpenGL format but I cant remember which format they
use now. Graphics books Other Libs often use the other format to OpenGL. In
fact maybe it would be best to have both and with corresponding row and column

As far as quaternions go I havent used them. I have used matrices firstly
because a matrix can encompass a complicated transform such as rotation of an
object around an arbitrary line not passing through the origin, whereas AFAIK a
quaternion is limited to rotation only, so the object must first be translated
so some part of the line is at the origin, then rotated, then translated back,
whereas a matrix can express this transform directly in one single object. Is
this the case or have I got it wrong? however I am aware that quaternions are
meant to be much quicker.

> 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.

Wow that sounds like a lot of work. It sounds like your own graphics library is
sophisticated, so it will be interesting to see some of that and
perhaps the work should consist more of incorporating others efforts into yours

> So I
> will be able to perform numreous benchmarks and unit tests to compare
> both libraries (both compuational correctness and speed).

Well ... For my original version of pqs I was quite surprised at how well, when
optimised, the quantity types compared to using inbuilt types, but that was only
using VC7.1 optimiser. I too should do some tests of optimisation of pqs in
compilers I guess!

Andy Little

Boost list run by bdawes at, gregod at, cpdaniel at, john at