Skip to content

Commit f0fe8cc

Browse files
author
root
committed
complete assignment2
1 parent c952b0d commit f0fe8cc

File tree

9 files changed

+84
-56
lines changed

9 files changed

+84
-56
lines changed

.project_alt.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"*.cpp": {"alternate": "{}.hpp"},
3+
"*.hpp": {"alternate": "{}.cpp"}
4+
}

Assignment1/Assignment1/main.cpp

+14-45
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Eigen::Matrix4f get_model_matrix(float rotation_angle)
2929
Eigen::Matrix4f rotation;
3030
float angle = rotation_angle * M_PI / 180;
3131

32-
rotation << cos(angle), -sin(angle), 0, 0, sin(angle), cos(angle),0, 0,
32+
rotation << cosf(angle), -sinf(angle), 0, 0, sinf(angle), cosf(angle),0, 0,
3333
0, 0, 1, 0, 0, 0, 0, 1;
3434
model = rotation * model;
3535

@@ -62,59 +62,33 @@ Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
6262
return projection;
6363
}
6464

65-
//利用罗德里格斯旋转公式得到绕过原点任意直线的旋转矩阵
66-
Eigen::Matrix4f get_rotation(Vector3f axis, float angle) {
67-
Eigen::Matrix3f I = Eigen::Matrix3f::Identity();
68-
float ra = angle * M_PI / 180;
69-
Eigen::Matrix3f R, N;
70-
71-
N << 0, -axis.z(), axis.y(),
72-
axis.z(), 0, -axis.x(),
73-
-axis.y(), axis.x(), 0;
65+
//利用罗德里格斯公式得到绕任意过原点的轴的旋转矩阵
66+
Eigen:Matrix4f get_rotation(Vector3f axis, float angle) {
67+
Eigen::Matrix4f identity = Eigen::Matrix4f::Identity();
7468

75-
R << cosf(ra) * I + (1 - cosf(ra)) * axis * axis.transpose() + sinf(ra) * N;
76-
77-
Eigen::Matrix4f R_homo;
69+
float ra = angle * M_PI / 180;
70+
Eigen::Matrix3f n;
71+
n << 0, -axis.z, axis.y, axis.z, 0, -axis.x, -axis.y, axis.x, 0;
7872

79-
/*将旋转矩阵扩展成齐次坐标形式*/
80-
for(int i = 0; i < 4; i++){
81-
for(int j = 0;j < 4; j++){
82-
if(i == 3 || j == 3){
83-
if(i!=j)
84-
R_homo(i, j)=0;
85-
else
86-
R_homo(i, j)=1;
87-
}
88-
else{
89-
R_homo(i, j)=R(i, j);
90-
}
91-
}
92-
}
93-
return R_homo;
73+
return toMatrix4f(cosf(ra) * identity, (1 - cosf(ra)) * axis * axis.transpose, sinf(ra) * n)
9474
}
9575

96-
9776
int main(int argc, const char** argv)
9877
{
9978
float angle = 0;
10079
bool command_line = false;
101-
bool rodrigue_rotation = false;
10280
std::string filename = "output.png";
103-
104-
Eigen::Matrix4f rodrigueM;
10581

106-
if (argc >= 3) {
107-
if (std::string(argv[1]) == "-r") {
82+
if (argc >= 2) {
83+
if (argc[2] == "-r" && argc >= 3) {
10884
command_line = true;
10985
angle = std::stof(argv[2]); // -r by default
11086
if (argc == 4) {
11187
filename = std::string(argv[3]);
11288
}
113-
} else if (std::string(argv[1]) == "-c" && argc == 6) {
114-
angle = std::stof(argv[5]);
115-
rodrigue_rotation = true;
116-
Eigen::Vector3f axis(std::stof(argv[2]), std::stof(argv[3]), std::stof(argv[4]));
117-
rodrigueM = get_rotation(axis, angle);
89+
} else if(argc[2] == "-c" && argc = 5) {
90+
91+
11892
}
11993
}
12094

@@ -153,12 +127,7 @@ int main(int argc, const char** argv)
153127

154128
r.set_model(get_model_matrix(angle));
155129
r.set_view(get_view_matrix(eye_pos));
156-
157-
if (rodrigue_rotation) {
158-
r.set_projection(get_projection_matrix(45, 1, 0.1, 50) * rodrigueM);
159-
} else {
160-
r.set_projection(get_projection_matrix(45, 1, 0.1, 50));
161-
}
130+
r.set_projection(get_projection_matrix(45, 1, 0.1, 50));
162131

163132
r.draw(pos_id, ind_id, rst::Primitive::Triangle);
164133

Assignment2/õ+úþáüµíåµ×Â/main.cpp Assignment2/Assignment2/main.cpp

+24-3
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,35 @@ Eigen::Matrix4f get_view_matrix(Eigen::Vector3f eye_pos)
2525
Eigen::Matrix4f get_model_matrix(float rotation_angle)
2626
{
2727
Eigen::Matrix4f model = Eigen::Matrix4f::Identity();
28+
29+
Eigen::Matrix4f rotation;
30+
float angle = rotation_angle * M_PI / 180;
31+
32+
rotation << cos(angle), -sin(angle), 0, 0, sin(angle), cos(angle),0, 0,
33+
0, 0, 1, 0, 0, 0, 0, 1;
34+
model = rotation * model;
35+
2836
return model;
2937
}
3038

31-
Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio, float zNear, float zFar)
39+
Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
40+
float zNear, float zFar)
3241
{
33-
// TODO: Copy-paste your implementation from the previous assignment.
34-
Eigen::Matrix4f projection;
42+
Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();
43+
44+
float fov_angle = eye_fov * M_PI / 180;
45+
46+
float n = -zNear;
47+
float t = tan(fov_angle / 2) * zNear;
48+
float b = -t;
49+
float r = t * aspect_ratio;
50+
float l = -r;
51+
float f = -zFar;
3552

53+
projection << 2 * n /(r - l), 0, (l + r)/(l - r) , 0,
54+
0, 2 * n /(t-b), (b + r)/(b - t), 0,
55+
0, 0, (f + n)/(n - f), 2 * f * n / (f-n),
56+
0, 0 ,1, 0;
3657
return projection;
3758
}
3859

Assignment2/õ+úþáüµíåµ×Â/rasterizer.cpp Assignment2/Assignment2/rasterizer.cpp

+42-8
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include <opencv2/opencv.hpp>
1010
#include <math.h>
1111

12-
1312
rst::pos_buf_id rst::rasterizer::load_positions(const std::vector<Eigen::Vector3f> &positions)
1413
{
1514
auto id = get_next_id();
@@ -43,6 +42,24 @@ auto to_vec4(const Eigen::Vector3f& v3, float w = 1.0f)
4342
static bool insideTriangle(int x, int y, const Vector3f* _v)
4443
{
4544
// TODO : Implement this function to check if the point (x, y) is inside the triangle represented by _v[0], _v[1], _v[2]
45+
Eigen::Vector2f AB, BC, CA, AP, BP, CP, p;
46+
float a, b, c;
47+
p << x, y;
48+
AB = _v[1].head(2) - _v[0].head(2);
49+
AP = p -_v[0].head(2);
50+
BC = _v[2].head(2) - _v[1].head(2);
51+
BP = p -_v[1].head(2);
52+
CA = _v[0].head(2) - _v[2].head(2);
53+
CP = p -_v[2].head(2);
54+
a = AB[0] * AP[1] - AB[1] * AP[0];
55+
b = BC[0] * BP[1] - BC[1] * BP[0];
56+
c = CA[0] * CP[1] - CA[1] * CP[0];
57+
if (a > 0 && b > 0 && c > 0) {
58+
return true;
59+
} else if (a < 0 && b < 0 && c < 0) {
60+
return true;
61+
}
62+
return false;
4663
}
4764

4865
static std::tuple<float, float, float> computeBarycentric2D(float x, float y, const Vector3f* v)
@@ -108,14 +125,31 @@ void rst::rasterizer::rasterize_triangle(const Triangle& t) {
108125

109126
// TODO : Find out the bounding box of current triangle.
110127
// iterate through the pixel and find if the current pixel is inside the triangle
111-
112128
// If so, use the following code to get the interpolated z value.
113-
//auto[alpha, beta, gamma] = computeBarycentric2D(x, y, t.v);
114-
//float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
115-
//float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
116-
//z_interpolated *= w_reciprocal;
117-
118129
// TODO : set the current pixel (use the set_pixel function) to the color of the triangle (use getColor function) if it should be painted.
130+
int minX = std::min(std::min(v[0].x(), v[1].x()), v[2].x());
131+
int minY = std::min(std::min(v[0].y(), v[1].y()), v[2].y());
132+
int maxX = std::max(std::max(v[0].x(), v[1].x()), v[2].x());
133+
int maxY = std::max(std::max(v[0].y(), v[1].y()), v[2].y());
134+
135+
for (int x = minX; x < maxX; x++) {
136+
for (int y = minY; y < maxY; y++) {
137+
if (insideTriangle(x + 0.5, y + 0.5, t.v)) {
138+
auto[alpha, beta, gamma] = computeBarycentric2D(x + 0.5, y + 0.5, t.v);
139+
float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
140+
float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
141+
z_interpolated *= w_reciprocal;
142+
143+
int cur_index = get_index(x, y);
144+
if (z_interpolated < depth_buf[cur_index]) {
145+
depth_buf[cur_index] = z_interpolated;
146+
Vector3f vertex;
147+
vertex << x, y, z_interpolated;
148+
set_pixel(vertex, t.getColor());
149+
}
150+
}
151+
}
152+
}
119153
}
120154

121155
void rst::rasterizer::set_model(const Eigen::Matrix4f& m)
@@ -164,4 +198,4 @@ void rst::rasterizer::set_pixel(const Eigen::Vector3f& point, const Eigen::Vecto
164198

165199
}
166200

167-
// clang-format on
201+
// clang-format on

0 commit comments

Comments
 (0)