0% found this document useful (0 votes)
29 views5 pages

实验报告模板

Uploaded by

zongshuxu10
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views5 pages

实验报告模板

Uploaded by

zongshuxu10
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 5

1.

实验题目:

2. 本实验总体设计思路和主要函数解析

void drawScene(int angle) {


//将背景色设置为灰色
unsigned int background = mapRGBA(128, 128, 128, 255);
clearPixels(background);

//视口分割线
unsigned int white = mapRGBA(255, 255, 255, 255);
drawLine(0, h, CANVAS_WIDTH - 1, h, white);
drawLine(w, 0, w, CANVAS_HEIGHT - 1, white);

//种子填充椭圆
unsigned int gold = mapRGBA(255, 215, 0, 255);
drawHalfEllipse(CANVAS_WIDTH / 2, CANVAS_HEIGHT / 2, 100, 60, gold, angle);
drawLineRotate(CANVAS_WIDTH / 2 + 100, CANVAS_HEIGHT / 2 -
60,CANVAS_WIDTH / 2 + 100, CANVAS_HEIGHT / 2, gold, -angle);
drawLineRotate(CANVAS_WIDTH / 2 + 100, CANVAS_HEIGHT / 2 - 60,
CANVAS_WIDTH / 2 - 100, CANVAS_HEIGHT / 2 - 60, gold, angle);
drawLineRotate( CANVAS_WIDTH / 2 - 100, CANVAS_HEIGHT / 2,CANVAS_WIDTH /
2 - 100, CANVAS_HEIGHT / 2 - 60, gold, -angle);
drawCircle(CANVAS_WIDTH / 2 - 100, CANVAS_HEIGHT / 2, 100, gold, angle);
}

// 旋转函数
void rotatePoint(int cx, int cy, int angle, int& x, int& y) {
double radians = angle * M_PI / 180.0; // 使用更精确的 π 值
int nx = cx + (x - cx) * cos(radians) - (y - cy) * sin(radians);
int ny = cy + (x - cx) * sin(radians) + (y - cy) * cos(radians);
x = nx;
y = ny;
}

// 绘制半个椭圆并旋转
void drawHalfEllipse(int cx, int cy, int a, int b, unsigned int color, int angle) {
int a2 = a * a, b2 = b * b;
int x = 0, y = b, d = 4 * b2 + a2 - 4 * a2 * b;
int nx, ny;

// 绘制上半部分
while (2 * b2 * x < (2 * a2 * y - a2)) {
nx = x + cx;
ny = y + cy;
rotatePoint(rotate_x, rotate_y, angle, nx, ny);
setPixel(nx, ny, color);

nx = -x + cx;
ny = y + cy;
rotatePoint(rotate_x, rotate_y, angle, nx, ny);
setPixel(nx, ny, color);

if (d < 0)
d += 4 * (2 * b2 * x + 3 * b2);
else {
d += 4 * (2 * b2 * x - 2 * a2 * y + 2 * a2 + 3 * b2);
y--;
}
x++;
}

// 绘制下半部分
y = 0, x = a;
d = -4 * b2 * a + b2 + 4 * a2;
while (2 * b2 * x > (2 * a2 * y + a2)) {
nx = x + cx;
ny = y + cy;
rotatePoint(rotate_x, rotate_y, angle, nx, ny);
setPixel(nx, ny, color);

nx = -x + cx;
ny = y + cy;
rotatePoint(rotate_x, rotate_y, angle, nx, ny);
setPixel(nx, ny, color);

if (d <= 0)
d += 4 * (2 * a2 * y + 3 * a2);
else {
d += 4 * (-2 * b2 * x + 2 * a2 * y + 3 * a2 + 2 * b2);
x--;
}
y++;
}
}
// Bresenham 算法绘制直线
void drawLineRotate(int x1, int y1, int x2, int y2, unsigned int color, int angle) {
int dx = x2 - x1, dy = y2 - y1;

bool swapped = false;


// 如果斜率绝对值大于 1,交换 x 和 y
if (abs(dx) < abs(dy)) {
swap(x1, y1);
swap(x2, y2);
swapped = true;
}

// 如果起点在右,交换起点和终点
if (x1 > x2) {
swap(x1, x2);
swap(y1, y2);
}

// 如果直线走向为从上到下,则 y 的增量为-1
int ystep = 1;
dx = x2 - x1, dy = y2 - y1;
if (dy < 0) {
ystep = -1;
dy = -dy;
}

// 初始化
int d = 2 * dy - dx;
int x = x1, y = y1;
while (x <= x2) {
// 填充像素
int nx = x, ny = y;
rotatePoint(rotate_x, rotate_y, angle, nx, ny);
if (swapped) {
setPixel(ny, nx, color);
}
else {
setPixel(nx, ny, color);
}

x++; // 更新 x
// 更新 y 和 d
if (d > 0) {
y = y + ystep;
d -= 2 * dx;
}
d += 2 * dy;
}
}

//TODO:绘制圆
//cx,cy:圆心坐标
//r:半径
void drawCircle(int cx, int cy, int r, unsigned int color, int angle) {
int x = 0;
int y = r;
int d = 3 - 2 * r;
int nx, ny;

auto setRotatedPixel = [&](int x, int y) {


nx = x;
ny = y;
rotatePoint(cx, cy, angle, nx, ny);
setPixel(nx, ny, color);
};

setRotatedPixel(cx + x, cy + y);
setRotatedPixel(cx - x, cy + y);
setRotatedPixel(cx + x, cy - y);
setRotatedPixel(cx - x, cy - y);
setRotatedPixel(cx + y, cy + x);
setRotatedPixel(cx - y, cy + x);
setRotatedPixel(cx + y, cy - x);
setRotatedPixel(cx - y, cy - x);

while (y >= x) {
x++;
if (d > 0) {
y--;
d = d + 4 * (x - y) + 10;
}
else {
d = d + 4 * x + 6;
}
setRotatedPixel(cx + x, cy + y);
setRotatedPixel(cx - x, cy + y);
setRotatedPixel(cx + x, cy - y);
setRotatedPixel(cx - x, cy - y);
setRotatedPixel(cx + y, cy + x);
setRotatedPixel(cx - y, cy + x);
setRotatedPixel(cx + y, cy - x);
setRotatedPixel(cx - y, cy - x);
}
}

3. 实现过程:

主要是在基础算法的基础上加入计算对应点旋转的算法,并加在每个像素画在画布之前进行旋转。

3.1 遇到的问题:

drawHalfEllipse(CANVAS_WIDTH / 2, CANVAS_HEIGHT / 2, 100, 60, gold, angle);


drawLineRotate(CANVAS_WIDTH / 2 + 100, CANVAS_HEIGHT / 2 - 60,CANVAS_WIDTH
/ 2 + 100, CANVAS_HEIGHT / 2, gold, -angle);
drawLineRotate(CANVAS_WIDTH / 2 + 100, CANVAS_HEIGHT / 2 - 60,
CANVAS_WIDTH / 2 - 100, CANVAS_HEIGHT / 2 - 60, gold, angle);
drawLineRotate( CANVAS_WIDTH / 2 - 100, CANVAS_HEIGHT / 2,CANVAS_WIDTH / 2 -
100, CANVAS_HEIGHT / 2 - 60, gold, -angle);
drawCircle(CANVAS_WIDTH / 2 - 100, CANVAS_HEIGHT / 2, 100, gold, angle);

其中左右(水平情况时)矩形的两边在同时设置 angle 为正时旋转方向相反。

3.2 解决方法:

对两边的角度单独取反

3.3 程序运行结果

You might also like