# 头歌——计算机图形学——三角形填充

CG2-v2.0-三角形填充

### 一. 任务描述

1. 本关任务

2. 输入

(1) 三角形的三个顶点的坐标:
t0 = {125,50}， t1 = {300,200}， t2 ={200,350};
(2) 三角形区域为蓝色。

3. 输出程序运行结果为一个蓝色三角形区域，如下图所示：

``````#include "pngimage.h"
#include<stdio.h>
#include <iostream>

struct Vec2i
{
int x, y;
};

void triangle(Vec2i t0, Vec2i t1, Vec2i t2, PNGImage& image, PNGColor color) {
/********** 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; y<=t1.y; y++) {
int segment_height = t1.y-t0.y+1;    //be careful with divisions by zero
float alpha = (float)(y-t0.y)/total_height;      //edge t0t2
float beta  = (float)(y-t0.y)/segment_height;    //edge t0t1
Vec2i A,B;
A.y=B.y=y;
A.x = t0.x + (t2.x-t0.x)*alpha;
B.x = t0.x + (t1.x-t0.x)*beta;
if (A.x>B.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 <= t2.y; y++)//感觉这个就是上半部分。

{
int segment_height = t2.y-t1.y+1;
float alpha2 = (float)(y-t0.y)/total_height;      //edge t0t2
float beta2  = (float)(y-t1.y)/segment_height;    //edge t0t1
Vec2i A2,B2;
A2.y=B2.y=y;
A2.x = t0.x + (t2.x-t0.x)*alpha2;
B2.x = t1.x - (t1.x-t2.x)*beta2;
if (A2.x>B2.x) std::swap(A2.x, B2.x);
for (int x=A2.x; x<=B2.x; x++) {
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 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 encode
image.init(black);
/********** 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 image
image.write_png_file("../img_step3/test.png");
return 0;
}``````

### 一. 任务描述

1. 本关任务

2. 输入

(1) 三角形的三个顶点的坐标:
t0 = {50,50}， t1 = {300,200}， t2 ={200,350};
(2) 三角形颜色区域为绿色。

3. 输出

``````#include "pngimage.h"
#include<stdio.h>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <stdlib.h>

struct Vec2i
{
int x, y;
};
struct Vec3f
{
float x, y, z;
};

//cross Product
Vec3f 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 abc
Vec3f Barycentre(Vec2i p, Vec2i a, Vec2i b, Vec2i c)//判断p点是否在这个三角形中
{
/********** 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 box
void Triangle(Vec2i t0, Vec2i t1, Vec2i t2, PNGImage& image, PNGColor color)
{
/********** Begin ********/
int xmax,ymax,x,y;
xmax=400,ymax=400;

Vec2i A;
Vec3f v;

for(x=0;x<=xmax;x++)
for(y=0;y<=ymax;y++)
{
A.x=x;
A.y=y;
v=Barycentre(A, t0, t1, t2);
if(v.x>=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 encode
image.init(black);
/********** 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 image
image.write_png_file("../img_step2/test.png");
return 0;
}``````

### 一. 任务描述

1. 本关任务

2. 输入

(1) 三角形的三个顶点的坐标:
t0 = {50,50}， t1 = {300,200}， t2 ={200,350};
(2) 三角形区域为红色。

3. 输出

``````#include "pngimage.h"
#include<stdio.h>
#include <iostream>
#include <algorithm>
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;
}
//DotProduct
float DotProduct(float cp1,float cp2)
{
return cp1*cp2;
}
//Determine if P1 and P2 are on the same side
bool SameSide( Vec2i p,Vec2i a, Vec2i b, Vec2i c )//同侧判断法
{
/********** 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 triangle
float PointInTriangle(Vec2i p,Vec2i a, Vec2i b, Vec2i c)//判断点是否在三角形内部
{
/********** 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 box
void Triangle(Vec2i t0, Vec2i t1, Vec2i t2, PNGImage& image, PNGColor color)//这个就是绘制三角形
{
/********** Begin ********/
int xmax,ymax,x,y;
Vec2i A;
xmax=300,ymax=350;
for(x=0;x<=xmax;x++)
{
for(y=0;y<=ymax;y++)
{
A.x=x;
A.y=y;
if(PointInTriangle(A,t0,t1 ,t2 ))
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 encode
image.init(black);