sysy-data/hidden_functional_c/sy/36_rotate.sy

113 lines
2.2 KiB
Plaintext

#include "sylib.h"
#include <string.h>
#define MAX_WIDTH 1024
// const int MAX_WIDTH = 1024
#define MAX_HEIGHT 1024
int image[MAX_WIDTH * MAX_HEIGHT], width, height;
const float PI = 3.14159265359, TWO_PI = 6.28318530718, EPSILON = 1e-6;
float my_fabs(float x)
{
if (x > 0) {
return x;
}
return -x;
}
float p(float x) { return 3 * x - 4 * x * x * x; }
float my_sin_impl(float x)
{
if (my_fabs(x) <= EPSILON) {
return x;
}
return p(my_sin_impl(x / 3.0));
}
float my_sin(float x)
{
if (x > TWO_PI || x < -TWO_PI) {
int xx = x / TWO_PI;
x = x - xx * TWO_PI;
}
if (x > PI) {
x = x - TWO_PI;
}
if (x < -PI) {
x = x + TWO_PI;
}
return my_sin_impl(x);
}
float my_cos(float x) { return my_sin(x + PI / 2); }
int read_image()
{
if (getch() != 80 || getch() != 50)
return -1;
width = getint();
height = getint();
if (width > MAX_WIDTH || height > MAX_HEIGHT || getint() != 255)
return -1;
int y = 0;
while (y < height) {
int x = 0;
while (x < width) {
image[y * width + x] = getint();
x = x + 1;
}
y = y + 1;
}
return 0;
}
int rotate(int x, int y, float rad)
{
float sinma = my_sin(rad), cosma = my_cos(rad);
int hwidth = width / 2, hheight = height / 2;
int xt = x - hwidth, yt = y - hheight;
int src_x = xt * cosma - yt * sinma + hwidth,
src_y = xt * sinma + yt * cosma + hheight;
if (src_x < 0 || src_x >= width || src_y < 0 || src_y >= height)
return 0;
return image[src_y * width + src_x];
}
void write_pgm(float rad)
{
putch(80);
putch(50);
putch(10); // P2
putint(width);
putch(32);
putint(height);
putch(32); // width height
putint(255);
putch(10); // 255
int y = 0;
while (y < height) {
int x = 0;
while (x < width) {
putint(rotate(x, y, rad));
putch(32);
x = x + 1;
}
putch(10);
y = y + 1;
}
}
int main()
{
memset(image, 0, MAX_WIDTH * MAX_HEIGHT);
float rad = getfloat();
getch();
if (read_image() < 0)
return -1;
write_pgm(rad);
return 0;
}