第1关:扫描线填充法、
#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) {
// 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; y<=t1.y; y++) {
int segment_height = t1.y-t0.y+1; //be careful with divisions by
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);
// 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 image
image.write_png_file("../img_step3/test.png");
return 0;
}
第2关:重心坐标填充
#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)
{
// Please add your code here
/********** Begin ********/
Vec3f v1,v2,v3,v4;
v1.x = c.x - a.x; v1.y = b.x - a.x; v1.z = a.x - p.x;
v2.x = c.y - a.y; v2.y = b.y - a.y; v2.z = a.y - p.y;
v3.x = -1; v3.y = 1; v3.z = 1;
Vec3f u = cross(v1, v2);
v4.x = 1.f - (u.x + u.y) / u.z; v4.y = u.y / u.z; v4.z = u.x / u.z;
if (abs(u.z) < 1)
return v3;
return v4;
/********** End ********/
}
// Please draw point to make a triangle in bounding box
void Triangle(Vec2i t0, Vec2i t1, Vec2i t2, PNGImage& image, PNGColor color)
{
// Please add your code here
/********** Begin ********/
int minX = min(min(t0.x, t1.x), t2.x);
int maxX = max(max(t0.x, t1.x), t2.x);
int minY = min(min(t0.y, t1.y), t2.y);
int maxY = max(max(t0.y, t1.y), t2.y);
Vec2i P;
for (int i = minX; i <= maxX; i++)
{
for (int j = minY; j <= maxY; j++)
{
P.x = i;
P.y = j;
Vec3f bc_screen = Barycentre(P, t0, t1, t2);
if (bc_screen.x <0 || bc_screen.y <0 || bc_screen.z < 0)
continue;
image.set(i, j, 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);
// Please add your code here
/********** Begin ********/
Vec2i t0 = { 50 ,50 }, t1 = { 300 ,200 }, t2 = { 200 ,350 };
Triangle( t0, t1 ,t2 , image,green );
/********** 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;
}
第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 p1,Vec2i p2, Vec2i a, Vec2i b )
{
// Please add your code here
/********** Begin ********/
Vec2i i,j,k;
i.x=b.x-a.x; i.y=b.y-a.y;
j.x=p1.x-a.x; j.y=p1.y-a.y;
k.x=p2.x-a.x; k.y=p2.y-a.y;
float cp1 = CrossProduct(i, j),
cp2 = CrossProduct(i, k);
if (DotProduct(cp1, cp2) >= 0)
return true;
else
return false;
/********** End **********/
}
//Determine the point coordinates are in the triangle
float 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 true;
else
return false;
/********** End **********/
}
// Please draw point in bounding box
void Triangle(Vec2i t0, Vec2i t1, Vec2i t2, PNGImage& image, PNGColor color)
{
// Please add your code here
/********** Begin ********/
int minX = min(min(t0.x, t1.x), t2.x);
int maxX = max(max(t0.x, t1.x), t2.x);
int minY = min(min(t0.y, t1.y), t2.y);
int maxY = max(max(t0.y, t1.y), t2.y);
for (int i = minX; i <= maxX; i++)
{
for (int j = minY; j <= maxY; j++)
{
Vec2i p;
p.x=i;
p.y=j;
if (PointInTriangle(p , t0 , t1 , t2)==true)
{
image.set(i, j, 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);
// Please add your code here
/********** Begin ********/
Vec2i t0 = { 50 , 50 }, t1 = { 300 , 200 }, t2 = { 200 ,350 };
Triangle( t0,t1 ,t2 , image,red );
/********** End **********/
image.flip_vertically(); // i want to have the origin at the left bottom corner of the image
image.write_png_file("../img_step1/test.png");
return 0;
}