CG2-v2.0-三角形填充
第一关.扫描线填充法
一. 任务描述
1. 本关任务
了解和掌握扫描线填充法,实现对三角形区域进行填充,具体要求如下: (1) 补全triangle函数; (2) 将main函数中的三角形顶点坐标和triangle函数参数补充完整。
2. 输入
(1) 三角形的三个顶点的坐标:
t0 = {125,50}, t1 = {300,200}, t2 ={200,350};
(2) 三角形区域为蓝色。
3. 输出程序运行结果为一个蓝色三角形区域,如下图所示:
#include "pngimage.h"#include#include struct Vec2i{int x, y;};void triangle(Vec2i t0, Vec2i t1, Vec2i t2, PNGImage& image, PNGColor color) { // Please add your code here /********** Begin ********/ if (t0.y>t1.y) std::swap(t0, t1); if (t0.y>t2.y) std::swap(t0, t2); if (t1.y>t2.y) std::swap(t1, t2); int total_height = t2.y-t0.y; for (int y=t0.y; yB.x) std::swap(A.x, B.x); for (int x=A.x; x<=B.x; x++) { image.set(x, y, color); } } for (int y = t1.y; y B2.x) std::swap(A2.x, B2.x); for (int x=A2.x; x in.size() in encodeimage.init(black); // Please add your code here /********** Begin ********/ Vec2i t0 = {125 ,50 }, t1 = {300 , 200}, t2 = {200 ,350 };triangle( t0,t1 ,t2, image,PNGColor(0, 255, 255, 255) ); /********** End **********/image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file("../img_step3/test.png");return 0;}
第2关:重心坐标填充法
一. 任务描述
1. 本关任务
了解和掌握重心坐标法,以便能够对三角形区域进行填充,具体要求如下: (1) 补全Triangle和Barycenter函数; (2) 将main函数中的三角形顶点坐标和Triangle函数参数补充完整。
2. 输入
(1) 三角形的三个顶点的坐标:
t0 = {50,50}, t1 = {300,200}, t2 ={200,350};
(2) 三角形颜色区域为绿色。
3. 输出
程序运行结果为一个绿色三角形区域,如下图所示:
#include "pngimage.h"#include#include #include #include #include struct Vec2i{int x, y;};struct Vec3f{float x, y, z;};//cross ProductVec3f cross(const Vec3f& v1, const Vec3f& v2)//我的妈呀,这是叉乘{ Vec3f v3; v3.x = v1.y * v2.z - v1.z * v2.y; v3.y = v1.z * v2.x - v1.x * v2.z; v3.z = v1.x * v2.y - v1.y * v2.x; return v3;}//Determine the point p coordinates are in the triangle abcVec3f Barycentre(Vec2i p, Vec2i a, Vec2i b, Vec2i c)//判断p点是否在这个三角形中{ // Please add your code here /********** Begin ********/ Vec3f s[2]; s[0].x = c.x-a.x; s[0].y = b.x-a.x; s[0].z = a.x-p.x; s[1].x = c.y-a.y; s[1].y = b.y-a.y; s[1].z = a.y-p.y; /* for (int i=2; i--; ) { s[i][0] = c[i]-a[i]; s[i][1] = b[i]-a[i]; s[i][2] = a[i]-p[i]; }*/ Vec3f u = cross(s[0], s[1]); Vec3f v; if (abs(u.z) > 1e-2) { v.x = 1.0-(u.x+u.y)/u.z; v.y = u.y/u.z; v.z = u.x/u.z; } else { v.x = -1; v.y = 1; v.z = 1; } return v; /*if (std::abs(u[2])>1e-2) return Vec3f(1.f-(u.x+u.y)/u.z, u.y/u.z, u.x/u.z); return Vec3f(-1,1,1); */ /********** End ********/}// Please draw point to make a triangle in bounding boxvoid Triangle(Vec2i t0, Vec2i t1, Vec2i t2, PNGImage& image, PNGColor color){ // Please add your code here /********** Begin ********/ int xmax,ymax,x,y; xmax=400,ymax=400; Vec2i A; Vec3f v; for(x=0;x<=xmax;x++) for(y=0;y=0&&v.y>=0&&v.z>=0) { image.set(x,y,color); } }} /********** End **********/int main(int argc, char** argv) {PNGColor white = PNGColor(255, 255, 255, 255);PNGColor black = PNGColor(0, 0, 0, 255);PNGColor red = PNGColor(255, 0, 0, 255); PNGColor green = PNGColor(0, 255, 0, 255); PNGColor blue = PNGColor(0, 255, 255, 255);int width = 400;int height = 400;PNGImage image(width, height, PNGImage::RGBA); //Error when RGB because lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size() in encodeimage.init(black); // Please add your code here /********** Begin ********/ Vec2i t0 = {50 ,50 }, t1 = {300 ,200 }, t2 = {200 ,350 }; Triangle( t0,t1 ,t2 , image, PNGColor(0, 255, 0, 255) ); /********** End **********/image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file("../img_step2/test.png");return 0;}
第3关:同侧判断填充法
一. 任务描述
1. 本关任务
了解和掌握同侧判断算法,以便能够对三角形区域进行填充,具体要求如下: (1) 并补全Triangle、SameSide和PointInTriangle函数; (2) 将main函数中的三角形顶点坐标和Triangle函数参数补充完整。
2. 输入
(1) 三角形的三个顶点的坐标:
t0 = {50,50}, t1 = {300,200}, t2 ={200,350};
(2) 三角形区域为红色。
3. 输出
程序运行结果为一个红色三角形区域,如下图所示:
#include "pngimage.h"#include#include #include using namespace std;struct Vec2i{int x, y;};//Cross product float CrossProduct(Vec2i a,Vec2i b){ return a.x * b.y - b.x * a.y;}//DotProductfloat DotProduct(float cp1,float cp2){ return cp1*cp2;}//Determine if P1 and P2 are on the same sidebool SameSide( Vec2i p,Vec2i a, Vec2i b, Vec2i c )//同侧判断法{ // Please add your code here /********** Begin ********/ /*float cp3,cp4; cp3=CrossProduct(ba,p1-a); cp4=CrossProduct(ba,p2-a); if (DotProduct(cp3,cp4)>=0) return TRUE;*/ Vec2i AB = {b.x - a.x, b.y - a.y}; Vec2i AC = {c.x - a.x, c.y - a.y}; Vec2i AP = {p.x - a.x, p.y - a.y}; float v1 = CrossProduct(AB, AC); float v2 = CrossProduct(AB, AP); if (DotProduct(v1, v2) >= 0) return 1; else return 0; /********** End **********/}//Determine the point coordinates are in the trianglefloat PointInTriangle(Vec2i p,Vec2i a, Vec2i b, Vec2i c)//判断点是否在三角形内部{ // Please add your code here /********** Begin ********/ /* if(SameSide(p,a,b,c)&&SameSide(p,b,a,c)&&SameSide(p,c,a,b)) return 1;*/ return SameSide(a, b, c, p) && SameSide(b, c, a, p) && SameSide(c, a, b, p); /********** End **********/}// Please draw point in bounding boxvoid Triangle(Vec2i t0, Vec2i t1, Vec2i t2, PNGImage& image, PNGColor color)//这个就是绘制三角形{ // Please add your code here /********** Begin ********/ int xmax,ymax,x,y; Vec2i A; xmax=300,ymax=350; for(x=0;x<=xmax;x++) { for(y=0;y in.size() in encodeimage.init(black); // Please add your code here /********** Begin ********/ Vec2i t0 = { 50 , 50 }, t1 = {300 ,200 }, t2 = {200 ,350 }; Triangle(t0 ,t1 , t2 , image, PNGColor(255, 0, 0, 255)); /********** End **********/image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file("../img_step1/test.png");return 0;}