スプライン その 7
あまり綺麗なコードではないが,ノットを使用しないで以前のコードと同様の内容.
Vd4A b_spline (const Vd4A& pnts_,const size_t order_,const size_t div_c_=2)
{
Vd4A pnts = pnts_ ;
size_t order = order_ ;
size_t div_c = div_c_ ;
if (pnts.size() < 3) { return pnts ; }
if (order < 2) { return pnts ; }
if (div_c < 2) { div_c = 2 ; }
if (div_c >10) { div_c =10 ; }
size_t degree = order-1 ;
bool p_open = true ;
{
Vd4 p0p = pnts[0] ;
Vd4 p1p = pnts[0] ;
Vd4 p_p = pnts[pnts.size()-1] ;
Vd4 plp = pnts[pnts.size()-1] ;
Vd4 p_0 = pnts[0] ;
Vd4 p_l = pnts[pnts.size()-1] ;
bool is_same = true ;
{
for (size_t index=1 ; index<pnts.size() ; index++) {
if (p_0 != pnts[index]) {
is_same = false ;
break ;
}
}
}
if (!is_same && p_0 == p_l) { // close
p0p = pnts[pnts.size()-3] ;
p1p = pnts[pnts.size()-2] ;
p_p = pnts[1] ;
plp = pnts[2] ;
p_open = false ;
}
if (p_open) {
switch (degree) {
case 9 : pnts.insert(pnts.begin(),p_0) ; pnts.push_back(p_l) ;
case 8 : pnts.insert(pnts.begin(),p_0) ; pnts.push_back(p_l) ;
case 7 : pnts.insert(pnts.begin(),p_0) ; pnts.push_back(p_l) ;
case 6 : pnts.insert(pnts.begin(),p_0) ; pnts.push_back(p_l) ;
case 5 : pnts.insert(pnts.begin(),p_0) ; pnts.push_back(p_l) ;
case 4 : pnts.insert(pnts.begin(),p_0) ; pnts.push_back(p_l) ;
case 3 : pnts.insert(pnts.begin(),p_0) ; pnts.push_back(p_l) ;
case 2 : pnts.insert(pnts.begin(),p_0) ; pnts.push_back(p_l) ;
default : break ;
}
}
else {
if (degree > 5) {
degree = 5 ;
order = degree+1 ;
}
switch (degree) {
case 2 : pnts.push_back(p_p) ; break ;
case 3 : pnts.push_back(p_p) ; pnts.push_back(plp) ; break ;
case 4 : pnts.insert(pnts.begin()+0,p1p) ;
pnts.push_back(p_p) ; pnts.push_back(plp) ; break ;
case 5 : pnts.insert(pnts.begin()+0,p0p) ;
pnts.insert(pnts.begin()+1,p1p) ;
pnts.push_back(p_p) ; pnts.push_back(plp) ; break ;
default : break ;
}
}
}
Vd4A vd3a ;
for (double j=degree*div_c ; j<=pnts.size()*div_c ; j++) {
double t = j/div_c ;
Vd4 pnt ;
for (size_t i=0 ; i<pnts.size() ; i++) {
double r = BS_basis(t,order,i) ;
pnt.x += pnts[i].x * r ;
pnt.y += pnts[i].y * r ;
pnt.z += pnts[i].z * r ;
}
vd3a.push_back(pnt) ;
}
return vd3a ;
}
これで良いかはっきりわかってないが,ノットの生成.
v_double BS_make_knot (const Vd4A& pnts,const size_t order)
{
v_double knot ;
size_t degree = order - 1 ;
{
for (size_t index0=0 ; index0< degree ; index0++) {
knot.push_back(0) ;
}
for (size_t index_=0 ; index_< pnts.size()-degree ; index_++) {
knot.push_back(index_) ;
}
for (size_t indexL=0 ; indexL< degree+1 ; indexL++) {
knot.push_back(pnts.size()-degree) ;
}
}
return knot ;
}
「制御点 8 個,次数(degree) 2」で求まったノットは,
0 0 0 1 2 3 4 5 6 6 6
ノットの数は,8 + 2 + 1
前後するが,内部ノットのみ生成.
0 1 2 3 4 5 6 7 8 9 10
閉じている場合は,制御点を繰り返す.
for (size_t index=1 ; index<pnts.size() && index<degree ; index++) {
Vd4 pnt = pnts[index] ;
pnts.push_back(pnt) ;
}
0 1 2 3 4 5 6 7 8 9 10 11 12