On Jan 27, 10:33 am, "(e-mail address removed)"
vector to represent points then it is possible to do this summation,
basicly thats wrong.
Not so. You can find a point p between p1 and p2
p = (p1 + p2)/2;
You can also do this for n points.
Heres a post from Richard Heathfield on comp.programming to do a
bezier:
http://tinyurl.com/yttted
Just to bring this back to C++. At the end a version using my off line
quanta lib, which I may one day get round to reworking and making
publicly available as a new version of my old quan library:
http://sourceforge.net/projects/quan
(N.B) The following wont work with the sourceforge version of quan:
/*
after a post on comp.programming thread font curves from Richard
Heathfield"
*/
#include <quanta/quan/quick_start/length.hpp>
#include <quanta/seq/vector/vector2.hpp>
#include <quanta/seq/vector/vector3.hpp>
#include <quanta/seq/vector/vector4.hpp>
#include <quanta/seq/vector/vector5.hpp>
#include <quanta/seq/out/sequence.hpp>
#include <stdexcept>
namespace impl{
// implement pascal's Triangle
// for various control point combos...
template <int NumCtPoints, int Iter>
struct get_bezier_constant;
// specialisation for 4 control points
template <> struct get_bezier_constant<4,0>
: std::tr1::integral_constant<int,1>{};
template <> struct get_bezier_constant<4,1>
: std::tr1::integral_constant<int,3>{};
template <> struct get_bezier_constant<4,2>
: std::tr1::integral_constant<int,3>{};
template <> struct get_bezier_constant<4,3>
: std::tr1::integral_constant<int,1>{};
// specialisation for 5 control points
template <> struct get_bezier_constant<5,0>
: std::tr1::integral_constant<int,1>{};
template <> struct get_bezier_constant<5,1>
: std::tr1::integral_constant<int,4>{};
template <> struct get_bezier_constant<5,2>
: std::tr1::integral_constant<int,6>{};
template <> struct get_bezier_constant<5,3>
: std::tr1::integral_constant<int,4>{};
template <> struct get_bezier_constant<5,4>
: std::tr1::integral_constant<int,1>{};
// functor to do the calc :
namespace detail{
//internal calc
template <int Iter> struct bezier_impl_eval;
// use compile time recursion to do the calc...
//'bezier_impl_eval<0>' is the compile time
//loop terminating condition
template <>
struct bezier_impl_eval<0>
{
// result type deduction
// CtrlPtSeq is a model of TypeSequence,
// a sequence whose length is known at compiletime
// can be doubles or types representing length
//in physical units etc ( as shown below
template <typename CtrlPtSeq,typename V>
struct apply : quanta::meta::binary_op<
V,
quanta::meta::times,
typename quanta::seq::at said:
>::type // at is equivalenat of s[0]
>{};
// calc function
template <typename CtrlPtSeq,typename V>
typename apply<CtrlPtSeq,V>::type
operator()(CtrlPtSeq const & s,V const & v)const
{
using quanta::seq::num_elements;
return get_bezier_constant<
num_elements said:
* quanta::quan:
ow<num_elements<
CtrlPtSeq>::value-1
* quanta::seq::at<0,quanta::fun::as_cref>()(s);
};
};
// non zero iterations
template <int Iter>
struct bezier_impl_eval{
// result type deduction
// recursively compute result type
//from results of previous iterations
template <typename CtrlPtSeq,typename V>
struct apply : quanta::meta::binary_op<
typename bezier_impl_eval<
Iter-1
>::template apply<CtrlPtSeq,V>::type,
quanta::meta:
lus,
typename quanta::seq::at<
Iter,quanta::fun::as_cref
>::template apply<CtrlPtSeq>::type
>{};
template <typename CtrlPtSeq,typename V>
typename apply<CtrlPtSeq,V>::type
operator()(CtrlPtSeq const & s,V const & v)const
{
using quanta::seq::num_elements;
return bezier_impl_eval<Iter-1>()(s,v)
// do calc recursively
+ get_bezier_constant<
num_elements said:
* quanta::quan:
ow<Iter>(v)
// pow is equivalent std:
ow(d,n)
//with compile time bezier_impl_eval on exp
* quanta::quan:
ow<num_elements<
CtrlPtSeq
>::value - (Iter + 1)>(1 - v)
* quanta::seq::at<Iter,quanta::fun::as_cref>()(s);
}
};
}
//Holds a sequence of ctrl pts
//auto detects algorith constants from length of sequence
template <typename CtrlPtSeq>
struct get_bezier_impl{
// ctor argument is the control point sequence
// to be evaluated
get_bezier_impl( CtrlPtSeq const & s_in): s(s_in){}
public:
// result of functor is result_type of final eval
template <typename V>
struct apply : detail::bezier_impl_eval<
quanta::seq::num_elements said:
>::template apply<CtrlPtSeq,V>{};
// V is arithmetic
template <typename V>
typename apply<V>::type
operator()(V const & v)const
{
if((v >= V(0)) && (v <= V(1))){
return detail::bezier_impl_eval<
quanta::seq::num_elements said:
}
throw std:
ut_of_range("bezier pos out of range");
}
private:
CtrlPtSeq const & s;
};
}
// function removes requirement on explicit template param.
template <typename CtrlPtSeq>
inline
impl::get_bezier_impl<CtrlPtSeq>
bez_calculator(CtrlPtSeq const & s)
{
return impl::get_bezier_impl<CtrlPtSeq>(s);
}
// for physical quantities
namespace si = quanta::quan::quick_start;
template <typename CtPts>
void do_bezier_pt( CtPts const & s, double const & p)
{
std::cout << "With ctrl pts :\n";
for_(s,quanta::fun:
utput(std::cout,"\n"));
std::cout << "At " << p << " result point = "
<< bez_calculator(s)(p) << "\n\n";
}
int main()
{
try{
// type of sequence of ctrl points for
// 2d points of length in mm.
typedef si::length::mm mm;
typedef quanta::seq::vector2<mm,mm> pt2;
typedef quanta::seq::vector4<pt2,pt2,pt2,pt2> ct_pts2d4;
ct_pts2d4 pts2(
pt2(mm(0),mm(0)),
pt2(mm(0.1),mm(0.1)),
pt2(mm(2),mm(1)),
pt2(mm(3),mm(1))
);
do_bezier_pt(pts2,0);
do_bezier_pt(pts2,0.5);
do_bezier_pt(pts2,1);
// also works for 3d points...
typedef quanta::seq::vector3<mm,mm,mm> pt3;
typedef quanta::seq::vector4<pt3,pt3,pt3,pt3> ct_pts3D4;
ct_pts3D4 pts3(
pt3(mm(0),mm(0),mm(0)),
pt3(mm(0.1),mm(0.1),mm(0.1)),
pt3(mm(2),mm(1),mm(-1)),
pt3(mm(3),mm(1),mm(0))
);
do_bezier_pt(pts3,0.5);
typedef quanta::seq::vector5<pt3,pt3,pt3,pt3,pt3> ct_pts3D5;
ct_pts3D5 pts3a(
pt3(mm(0),mm(0),mm(0)),
pt3(mm(0.1),mm(0.1),mm(0.1)),
pt3(mm(0.2),mm(0.3),mm(0.8)),
pt3(mm(2),mm(1),mm(-1)),
pt3(mm(3),mm(1),mm(0))
);
do_bezier_pt(pts3a,0.1);
}
catch ( std::exception & e){
std::cout << "Caught \"" << e.what() << "\"";
}
}
/* output:
With ctrl pts :
(0 mm,0 mm)
(0.1 mm,0.1 mm)
(2 mm,1 mm)
(3 mm,1 mm)
At 0 result point = (0 mm,0 mm)
With ctrl pts :
(0 mm,0 mm)
(0.1 mm,0.1 mm)
(2 mm,1 mm)
(3 mm,1 mm)
At 0.5 result point = (1.1625 mm,0.5375 mm)
With ctrl pts :
(0 mm,0 mm)
(0.1 mm,0.1 mm)
(2 mm,1 mm)
(3 mm,1 mm)
At 1 result point = (3 mm,1 mm)
With ctrl pts :
(0 mm,0 mm,0 mm)
(0.1 mm,0.1 mm,0.1 mm)
(2 mm,1 mm,-1 mm)
(3 mm,1 mm,0 mm)
At 0.5 result point = (1.1625 mm,0.5375 mm,-0.3375 mm)
With ctrl pts :
(0 mm,0 mm,0 mm)
(0.1 mm,0.1 mm,0.1 mm)
(0.2 mm,0.3 mm,0.8 mm)
(2 mm,1 mm,-1 mm)
(3 mm,1 mm,0 mm)
At 0.1 result point = (0.04638 mm,0.04744 mm,0.06444 mm)
*/