|
Toshihiro Shimizu |
890ddd |
#include <cmath> // sqrt() sin() cos()</cmath>
|
|
Toshihiro Shimizu |
890ddd |
#include <vector> // std::vector</vector>
|
|
Toshihiro Shimizu |
890ddd |
#include <stdexcept> // std::domain_error()</stdexcept>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
bool inside_polygon_(
|
|
Toshihiro Shimizu |
890ddd |
double radius, int odd_diameter, double xp, double yp, int polygon_num, double degree)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
ee259f |
double radian = degree * (M_PI / 180),
|
|
Toshihiro Shimizu |
890ddd |
add_radian = 2.0 * M_PI / polygon_num,
|
|
Toshihiro Shimizu |
890ddd |
x1 = 0, y1 = 0, x2, y2,
|
|
Toshihiro Shimizu |
890ddd |
xa = -odd_diameter,
|
|
Toshihiro Shimizu |
890ddd |
xb = -odd_diameter;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int ii = 0; ii <= polygon_num; ++ii,
|
|
Toshihiro Shimizu |
890ddd |
radian += add_radian, x1 = x2, y1 = y2) {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* 注意:参照の図形と 計算結果の図形は左右反転する。
|
|
Toshihiro Shimizu |
890ddd |
そのため結果画像は左からCW回転となってしまう。
|
|
Toshihiro Shimizu |
890ddd |
数学的開始点(右)及び回転方向(CCW)とするため、
|
|
Toshihiro Shimizu |
890ddd |
内部で上下左右反転する。
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
x2 = -radius * cos(radian);
|
|
Toshihiro Shimizu |
890ddd |
y2 = -radius * sin(radian);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (ii <= 0) {
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* ypのy scanline上で交差
|
|
Toshihiro Shimizu |
890ddd |
((y2==y1==yp)の場合も)しない線分なら次へ */
|
|
Toshihiro Shimizu |
890ddd |
if (!(((y1 <= yp) && (yp <= y2)) ||
|
|
Toshihiro Shimizu |
890ddd |
((y2 <= yp) && (yp <= y1)))) {
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (y2 == y1) {
|
|
Toshihiro Shimizu |
890ddd |
if (((x1 <= xp) && (xp <= x2)) ||
|
|
Toshihiro Shimizu |
890ddd |
((x2 <= xp) && (xp <= x1))) {
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (xa == -odd_diameter) {
|
|
Toshihiro Shimizu |
890ddd |
/* (x2 - x1)/(y2 - y1)=(xa - x1)/(yp - y1);
|
|
Toshihiro Shimizu |
890ddd |
(xa - x1)=(yp - y1)*(x2 - x1)/(y2 - y1); */
|
|
Toshihiro Shimizu |
890ddd |
xa = (yp - y1) * (x2 - x1) / (y2 - y1) + x1;
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (xb == -odd_diameter) {
|
|
Toshihiro Shimizu |
890ddd |
xb = (yp - y1) * (x2 - x1) / (y2 - y1) + x1;
|
|
Toshihiro Shimizu |
890ddd |
if (((xa <= xp) && (xp <= xb)) ||
|
|
Toshihiro Shimizu |
890ddd |
((xb <= xp) && (xp <= xa))) {
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void attenuation_distribution_(
|
|
Toshihiro Shimizu |
890ddd |
std::vector<std::vector<double>> &lens_matrix, std::vector<int> &lens_offsets, std::vector<double *=""> &lens_starts, std::vector<int> &lens_sizes, int &odd_diameter, const double radius </int></double></int></std::vector<double>
|
|
Toshihiro Shimizu |
890ddd |
,
|
|
Toshihiro Shimizu |
890ddd |
const double curve
|
|
Toshihiro Shimizu |
890ddd |
,
|
|
Toshihiro Shimizu |
890ddd |
const int polygon_num
|
|
Toshihiro Shimizu |
890ddd |
,
|
|
Toshihiro Shimizu |
890ddd |
const double degree
|
|
Toshihiro Shimizu |
890ddd |
)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
double radius
|
|
Toshihiro Shimizu |
890ddd |
影響の半径
|
|
Toshihiro Shimizu |
890ddd |
1より大きい浮動小数値
|
|
Toshihiro Shimizu |
890ddd |
diameterはこの値から自動設定する
|
|
Toshihiro Shimizu |
890ddd |
double curve
|
|
Toshihiro Shimizu |
890ddd |
中心から周辺への下り具合(デフォルトは1)
|
|
Toshihiro Shimizu |
890ddd |
光り拡散の強弱
|
|
Toshihiro Shimizu |
890ddd |
zeroでない浮動小数値
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
lens_offsetsとlens_sizesで影響範囲を表わすmatrixを表わす
|
|
Toshihiro Shimizu |
890ddd |
radiusは影響円の半径
|
|
Toshihiro Shimizu |
890ddd |
matrix(縦横)サイズ(lens_offsets.size())は
|
|
Toshihiro Shimizu |
890ddd |
円(radius)が入る最小整数値でかつ、
|
|
Toshihiro Shimizu |
890ddd |
1以上の奇数(1,3,5,...)値
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
影響は上下反転、左右反転するので注意、以下説明図
|
|
Toshihiro Shimizu |
890ddd |
y
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
^
|
|
Toshihiro Shimizu |
890ddd |
| |\
|
|
Toshihiro Shimizu |
890ddd |
| | \
|
|
Toshihiro Shimizu |
890ddd |
| | * >
|
|
Toshihiro Shimizu |
890ddd |
| |\ | /
|
|
Toshihiro Shimizu |
890ddd |
| | \ |/
|
|
Toshihiro Shimizu |
890ddd |
| | * >P
|
|
Toshihiro Shimizu |
890ddd |
| | / |\
|
|
Toshihiro Shimizu |
890ddd |
| |/ | \
|
|
Toshihiro Shimizu |
890ddd |
| | * >
|
|
Toshihiro Shimizu |
890ddd |
| | /
|
|
Toshihiro Shimizu |
890ddd |
| |/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
y
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
^
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
Toshihiro Shimizu |
890ddd |
| \ * /
|
|
Toshihiro Shimizu |
890ddd |
| \ /
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
Toshihiro Shimizu |
890ddd |
| \ * / \ * /
|
|
Toshihiro Shimizu |
890ddd |
| \ / \ /
|
|
Toshihiro Shimizu |
890ddd |
| v v
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
| P : Target pixel
|
|
Toshihiro Shimizu |
890ddd |
| <,/,\,| : 影響範囲
|
|
Toshihiro Shimizu |
890ddd |
| * : 描画の結果
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (0.0 == curve) {
|
|
Toshihiro Shimizu |
890ddd |
//return false;
|
|
Toshihiro Shimizu |
890ddd |
throw std::domain_error("curve is zero");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
odd_diameter = static_cast<int>(ceil(radius * 2.0));</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (odd_diameter <= 1) {
|
|
Toshihiro Shimizu |
890ddd |
//return false;
|
|
Toshihiro Shimizu |
890ddd |
throw std::domain_error("diameter is equal less than 1");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (0 == (odd_diameter % 2)) {
|
|
Toshihiro Shimizu |
890ddd |
++odd_diameter;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
lens_matrix.resize(odd_diameter);
|
|
Toshihiro Shimizu |
890ddd |
for (int yy = 0; yy < odd_diameter; ++yy) {
|
|
Toshihiro Shimizu |
890ddd |
lens_matrix.at(yy).resize(odd_diameter);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
lens_offsets.resize(odd_diameter);
|
|
Toshihiro Shimizu |
890ddd |
lens_starts.resize(odd_diameter);
|
|
Toshihiro Shimizu |
890ddd |
lens_sizes.resize(odd_diameter);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
2.scanlineスタート位置とスタートポインタのセット
|
|
Toshihiro Shimizu |
890ddd |
3.scanlineサイズのセット
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double yp = 0.5 - (odd_diameter / 2.0);
|
|
Toshihiro Shimizu |
890ddd |
for (int yy = 0; yy < odd_diameter; ++yy, yp += 1.0) {
|
|
Toshihiro Shimizu |
890ddd |
lens_offsets.at(yy) = -1;
|
|
Toshihiro Shimizu |
890ddd |
lens_starts.at(yy) = 0;
|
|
Toshihiro Shimizu |
890ddd |
lens_sizes.at(yy) = -1;
|
|
Toshihiro Shimizu |
890ddd |
double xp = 0.5 - (odd_diameter / 2.0);
|
|
Toshihiro Shimizu |
890ddd |
for (int xx = 0; xx < odd_diameter; ++xx, xp += 1.0) {
|
|
Toshihiro Shimizu |
890ddd |
const double length = sqrt(xp * xp + yp * yp);
|
|
Toshihiro Shimizu |
890ddd |
if ((length <= radius) &&
|
|
Toshihiro Shimizu |
890ddd |
((polygon_num < 3) ||
|
|
Toshihiro Shimizu |
890ddd |
inside_polygon_(
|
|
Toshihiro Shimizu |
890ddd |
radius, odd_diameter,
|
|
Toshihiro Shimizu |
890ddd |
xp, yp, polygon_num, degree))) {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double val = 1.0 - (length / radius);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
val = pow(val, 1.0 / curve);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
lens_matrix.at(yy).at(xx) = val;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (lens_offsets.at(yy) < 0) {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
lens_offsets.at(yy) = xx;
|
|
Toshihiro Shimizu |
890ddd |
lens_starts.at(yy) = &lens_matrix.at(yy).at(xx);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
lens_matrix.at(yy).at(xx) = 0.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if ((0 <= lens_offsets.at(yy)) &&
|
|
Toshihiro Shimizu |
890ddd |
(lens_sizes.at(yy) < 0)) {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
lens_sizes.at(yy) = xx - lens_offsets.at(yy);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if ((0 <= lens_offsets.at(yy)) && (lens_sizes.at(yy) < 0)) {
|
|
Toshihiro Shimizu |
890ddd |
lens_sizes.at(yy) = odd_diameter - lens_offsets.at(yy);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double total = 0.0;
|
|
Toshihiro Shimizu |
890ddd |
for (unsigned int yy = 0; yy < lens_matrix.size(); ++yy) {
|
|
Toshihiro Shimizu |
890ddd |
for (unsigned int xx = 0; xx < lens_matrix.at(yy).size(); ++xx) {
|
|
Toshihiro Shimizu |
890ddd |
total += lens_matrix.at(yy).at(xx);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
for (unsigned int yy = 0; yy < lens_matrix.size(); ++yy) {
|
|
Toshihiro Shimizu |
890ddd |
for (unsigned int xx = 0; xx < lens_matrix.at(yy).size(); ++xx) {
|
|
Toshihiro Shimizu |
890ddd |
lens_matrix.at(yy).at(xx) /= total;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|