b448. 哈哈鏡

contents

  1. 1. Problem
  2. 2. Sample Input
  3. 3. Sample Output
  4. 4. Solution

Problem

進行圖片變形,效果類似哈哈鏡的作用。

對圖片水平中線進行座標 y' = sqrt(y) 變換,將靠近中線的像素盡可能地拉往中間,形成延伸的變形效果。

Sample Input

1
2
1 1
1 2 3

Sample Output

1
2
1 1
1 2 3

Solution

計算公式

  • 中線之上 (H/2) - pow(i-H/2, 2)/ (H/2)
  • 中線之下 pow(i-H/2, 2)/ (H/2) + H/2

分別套用後,逆轉換到原圖上,進行最近鄰居查找,。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <bits/stdc++.h>
using namespace std;
class IMAGE {
public:
struct Pixel {
int r, g, b;
Pixel(int x = 0, int y = 0, int z = 0):
r(x), g(y), b(z) {}
void read() {
scanf("%d %d %d", &r, &g, &b);
}
Pixel operator-(const Pixel &x) const {
return Pixel(r-x.r, g-x.g, b-x.b);
}
Pixel operator+(const Pixel &x) const {
return Pixel(r+x.r, g+x.g, b+x.b);
}
Pixel operator*(const double x) const {
return Pixel(r*x, g*x, b*x);
}
Pixel operator/(const double x) const {
return Pixel(r/x, g/x, b/x);
}
bool operator==(const Pixel &x) const {
return r == x.r && g == x.g && b == x.b;
}
void print() {
printf("%d %d %d", r, g, b);
}
int sum() {
return r + g + b;
}
int length() {
return abs(r) + abs(g) + abs(b);
}
int dist(Pixel x) {
return abs((r + g + b) - (x.r + x.g + x.b));
}
};
int W, H;
static const int MAXN = 256;
Pixel data[MAXN][MAXN], tmp[MAXN][MAXN];
void read() {
scanf("%d %d", &W, &H);
for (int i = 0; i < H; i++)
for (int j = 0; j < W; j++)
data[i][j].read();
}
void print() {
printf("%d %d\n", W, H);
for (int i = 0; i < H; i++)
for (int j = 0; j < W; j++)
data[i][j].print(), printf("%c", j == W-1 ? '\n' : ' ');
}
int isValid(int x, int y) {
return x >= 0 && y >= 0 && x < H && y < W;
}
void distorting_mirror() {
int rW = W, rH = H;
double ch = H / 2.0;
for (int i = 0; i < rH; i++) {
double x, y;
if (i < ch)
x = ch - pow(i-ch, 2)/ch;
else
x = pow(i-ch, 2)/ch + ch;
for (int j = 0; j < rW; j++) {
y = j;
int lx, rx, ly, ry;
lx = floor(x), rx = ceil(x);
ly = floor(y), ry = ceil(y);
int px[] = {lx, lx, rx, rx};
int py[] = {ly, ry, ly, ry};
int c = -1;
double mndist = 1e+30;
for (int k = 0; k < 4; k++) {
if (!isValid(px[k], py[k]))
continue;
double d = (x-px[k])*(x-px[k])+(y-py[k])*(y-py[k]);
if (c == -1 || mndist > d)
c = k, mndist = d;
}
assert (c >= 0);
tmp[i][j] = data[px[c]][py[c]];
}
}
W = rW, H = rH;
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
data[i][j] = tmp[i][j];
}
}
}
} image;
int main() {
image.read();
image.distorting_mirror();
image.print();
return 0;
}