#include #include #include /* std::copy() */ #include "igs_maxmin_slrender.h" #include "igs_maxmin_lens_matrix.h" void igs::maxmin::slrender::resize(const int odd_diameter, const int width, const bool alpha_ref_sw, std::vector> &tracks, std::vector &alpha_ref, std::vector &result) { tracks.resize(odd_diameter); for (int yy = 0; yy < odd_diameter; ++yy) { tracks.at(yy).resize(width + odd_diameter - 1); } if (alpha_ref_sw) { alpha_ref.resize(width); } result.resize(width); } void igs::maxmin::slrender::clear(std::vector> &tracks, std::vector &alpha_ref, std::vector &result) { result.clear(); alpha_ref.clear(); tracks.clear(); } void igs::maxmin::slrender::shift(std::vector> &tracks) { /* 先頭からtracks.end()-1番目の要素が先頭にくるように回転 */ std::rotate(tracks.begin(), tracks.end() - 1, tracks.end()); } namespace { double maxmin_(const double src, const bool min_sw, const std::vector &begin_ptr, const std::vector &lens_sizes, const std::vector> &lens_ratio) { if (min_sw) { /* 暗を広げる場合、反転して判断し、結果は反転して戻す */ double val = 1.0 - src; /* 反転して判断 */ const double rev_src = 1.0 - src; /* 反転して判断 */ for (unsigned yy = 0; yy < begin_ptr.size(); ++yy) { const int sz = lens_sizes.at(yy); if (sz <= 0) { continue; } const double *xptr = begin_ptr.at(yy); const double *rptr = &lens_ratio.at(yy).at(0); for (int xx = 0; xx < sz; ++xx, ++xptr, ++rptr) { double crnt = 1.0 - (*xptr); /* 反転して判断 */ /* 元値と同じか(反転してるので)小さい値は不要 */ if (crnt <= rev_src) { continue; } /* 元値との差に比率を掛けて結果値を出す */ crnt = rev_src + (crnt - rev_src) * (*rptr); /* 今までの中で(反転してるので)より大きいなら代入 */ if (val < crnt) { val = crnt; } } } return 1.0 - val; /* 結果は反転して戻す */ } /* Max */ double val = src; for (unsigned yy = 0; yy < begin_ptr.size(); ++yy) { const int sz = lens_sizes.at(yy); if (sz <= 0) { continue; } const double *xptr = begin_ptr.at(yy); const double *rptr = &lens_ratio.at(yy).at(0); for (int xx = 0; xx < sz; ++xx, ++xptr, ++rptr) { /* 元値と同じか小さい値は不要 */ if ((*xptr) <= src) { continue; } /* 元値との差に比率を掛けて結果値を出す */ const double crnt = src + ((*xptr) - src) * (*rptr); /* 今までの中でより大きいなら代入 */ if (val < crnt) { val = crnt; } } } return val; } void set_begin_ptr_(const std::vector> &tracks, const std::vector &lens_offsets, const int offset, std::vector &begin_ptr) { for (unsigned ii = 0; ii < lens_offsets.size(); ++ii) { begin_ptr.at(ii) = (0 <= lens_offsets.at(ii)) ? &tracks.at(ii).at(offset + lens_offsets.at(ii)) : 0; } } } /* --- tracksをレンダリングする --------------------------------------*/ void igs::maxmin::slrender::render( const double radius, const double smooth_outer_range, const int polygon_number, const double roll_degree , const bool min_sw , std::vector &lens_offsets, std::vector &lens_sizes, std::vector> &lens_ratio , const std::vector> &tracks /* RGBのどれか */ , const std::vector &alpha_ref /* alpha値で影響度合を決める */ , std::vector &result /* 計算結果 */ ) { /* 初期位置 */ std::vector begin_ptr(lens_offsets.size()); set_begin_ptr_(tracks, lens_offsets, 0, begin_ptr); /* 効果半径に変化がある場合 */ if (0 < alpha_ref.size()) { double before_radius = 0.0; for (unsigned xx = 0; xx < result.size(); ++xx) { /* 次の処理の半径 */ const double radius2 = alpha_ref.at(xx) * radius; /* ゼロ以上なら処理する */ if (0.0 < alpha_ref.at(xx)) { /* 前のPixelと違う大きさならreshapeする */ if (radius2 != before_radius) { igs::maxmin::reshape_lens_matrix( radius2, igs::maxmin::outer_radius_from_radius( radius2, smooth_outer_range), igs::maxmin::diameter_from_outer_radius(radius + smooth_outer_range), polygon_number, roll_degree, lens_offsets, lens_sizes, lens_ratio); set_begin_ptr_(tracks, lens_offsets, xx, begin_ptr); } /* 各ピクセルの処理 */ result.at(xx) = maxmin_(result.at(xx), min_sw, begin_ptr, lens_sizes, lens_ratio); } /* alpha_refがゼロなら変化なし */ /* 次の位置へ移動 */ for (unsigned ii = 0; ii < begin_ptr.size(); ++ii) { if (begin_ptr.at(ii) != 0) { ++begin_ptr.at(ii); } } if (radius2 != before_radius) { before_radius = radius2; } } } /* 効果半径が変わらない場合 */ else { for (unsigned xx = 0; xx < result.size(); ++xx) { /* 各ピクセルの処理 */ result.at(xx) = maxmin_(result.at(xx), min_sw, begin_ptr, lens_sizes, lens_ratio); /* 次の位置へ移動 */ for (unsigned ii = 0; ii < begin_ptr.size(); ++ii) { if (begin_ptr.at(ii) != 0) { ++begin_ptr.at(ii); } } } } }