games101 作业3

2023-11-14

遇到的问题:

1.项目才打开时无法运行。

解决方法:切换成c++17aa6198ca1d524ef9a37bc858a8c8945e.png

解决方法引用:Games101 作业3 环境问题 - 知乎

 注:知乎里面的关于越界限制的控制不适用,虽然可以解决部分作业的问题,但是在bump里面依然会出现越界错误。应该用以下大佬的代码。

 2.出现越界错误90f7da81535a4b80839815871eaa7bab.png

 解决方法:在头文件里面的texture.hpp里面增加限制

    Eigen::Vector3f getColor(float u, float v)
    {
        //以下两句为新增
        u = fmin(1, fmax(u, 0));
        v = fmin(1, fmax(v, 0));

        auto u_img = u * width;
        auto v_img = (1 - v) * height;
        auto color = image_data.at<cv::Vec3b>(v_img, u_img);
        return Eigen::Vector3f(color[0], color[1], color[2]);
    }

解决方法引用:【GAMES101】作业3(提高)与法线贴图原理和渲染管线框架分析

3.如何输入output.png normal这些。

4a7100422f294b538b7fbc9b006c1a6c.png

作业分析:

1. 修改函数 rasterize_triangle(const Triangle& t) in rasterizer.cpp: 在此处实现与作业 2 类似的插值算法,实现法向量、颜色、纹理颜色的插值。

        依然逐个像素判断是否在三角形内。前面代码都和作业2一样,只是在for循环内增加法向量、颜色、纹理颜色的插值。插值的方法框架也已经写好了,直接用就是。

(这点确实没想到。。想了很久gif.latex?%5Calpha%20%5Cbeta%20%5Cgamma该怎么用,最后还是参考了别人的才知道。)

static Vector3f interpolate(float alpha, float beta, float gamma, const Vector3f& vert1, const Vector3f& vert2, const Vector3f& vert3, float weight)
{
    return (alpha * vert1 + beta * vert2 + gamma * vert3) / weight;
}

static Vector2f interpolate(float alpha, float beta, float gamma, const Vector2f& vert1, const Vector2f& vert2, const Vector2f& vert3, float weight)
{
    auto u = (alpha * vert1[0] + beta * vert2[0] + gamma * vert3[0]);
    auto v = (alpha * vert1[1] + beta * vert2[1] + gamma * vert3[1]);

    u /= weight;
    v /= weight;

    return Vector2f(u, v);
}

知道了直接调用interpolate实现插值,那其他也没啥难度了,老师代码都给全了。

2. 修改函数 get_projection_matrix() in main.cpp: 将你自己在之前的实验中实现的投影矩阵填到此处,此时你可以运行 ./Rasterizer output.png normal来观察法向量实现结果。

        没什么疑问,直接把作业2的内容放上去就行了。

3. 修改函数 phong_fragment_shader() in main.cpp: 实现 Blinn-Phong 模型计算 Fragment Color.

16c9dd35dfd3437fa6530485215ed2db.png

 需要用到的:

dot()点乘

Norm()求向量长度

Normalized()求标准向量

pow(x,n)求n次方

cwiseProduct()向量对应值相乘。举个例子就是:gif.latex?A%3D%5Cbegin%7Bpmatrix%7D%201%5C%5C%202%5C%5C%203%20%5Cend%7Bpmatrix%7D%2CB%3D%5Cbegin%7Bpmatrix%7D%204%5C%5C%205%5C%5C%206%20%5Cend%7Bpmatrix%7DA.cwiseProduct%28B%29%3D%5Cbegin%7Bpmatrix%7D%201%5Ctimes%204%5C%5C%202%5Ctimes%205%5C%5C%203%5Ctimes%206%20%5Cend%7Bpmatrix%7D%3D%5Cbegin%7Bpmatrix%7D%204%5C%5C%2010%5C%5C%2018%20%5Cend%7Bpmatrix%7D

一个很好的解释:Blinn-Phong光照模型从定义到实现,一文就够了(1.5w字) - 知乎

4. 修改函数 texture_fragment_shader() in main.cpp: 在实现 Blinn-Phong的基础上,将纹理颜色视为公式中的 kd,实现 Texture Shading Fragment Shader.

f9ae56e2f3ea4de3acb78b30098a066b.png

 5.修改函数 bump_fragment_shader() in main.cpp: 在实现 Blinn-Phong 的 基础上,仔细阅读该函数中的注释,实现 Bump mapping.
按照老师给的注释挨着写上去,只是写上去没什么难度,难度在于理解代码。

6.修改函数 displacement_fragment_shader() in main.cpp: 在实现 Bump mapping 的基础上,实现 displacement mapping.

05566244afc74b0c800d8298e25fb417.png

5是实现凹凸贴图,6是实现置换贴图。代码只有一句需要修改,就是把point的位置实现真正的改变。老师的备注也是很详细的给出了。

 

代码部分

1.

void rst::rasterizer::rasterize_triangle(const Triangle& t, const array<Vector3f, 3>& view_pos) 
{
    auto v = t.toVector4();
//    std::tuple<float, float, float> angle(alpha, beta, gamma);
    float xmin = v[0][0] < (v[1][0] < v[2][0] ? v[1][0] : v[2][0]) ? v[0][0] : (v[1][0] < v[2][0] ? v[1][0] : v[2][0]);//最左边边界,最小值
    float xmax = v[0][0] > (v[1][0] > v[2][0] ? v[1][0] : v[2][0]) ? v[0][0] : (v[1][0] > v[2][0] ? v[1][0] : v[2][0]);//最右边边界,最大值
    float ymin = v[0][1] < (v[1][1] < v[2][1] ? v[1][1] : v[2][1]) ? v[0][1] : (v[1][1] < v[2][1] ? v[1][1] : v[2][1]);//最矮,最小值
    float ymax = v[0][1] > (v[1][1] > v[2][1] ? v[1][1] : v[2][1]) ? v[0][1] : (v[1][1] > v[2][1] ? v[1][1] : v[2][1]);//最高,最大值

    int x_min = floor(xmin);
    int x_max = ceil(xmax);
    int y_min = floor(ymin);
    int y_max = ceil(ymax);
    //遍历所有坐标
    for (int x = x_min; x <= x_max; x++) {
        for (int y = y_min; y <= y_max; y++) {
            if (insideTriangle(x, y, t.v)) {//如果在三角形内
                auto [alpha, beta, gamma] = computeBarycentric2D(x+0.5, y+0.5, t.v);
//               angle = computeBarycentric2D(x+0.5, y+0.5, t.v);
                float Z = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());    //根据质心坐标计算实际的z值
                float zp = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
                zp *= Z;

                if (zp < depth_buf[get_index(x, y)]) {
                    depth_buf[get_index(x, y)] = zp;
                    auto interpolated_color=interpolate(alpha,beta,gamma,t.color[0],t.color[1],t.color[2],1);
                    auto interpolated_normal=interpolate(alpha, beta, gamma, t.normal[0], t.normal[1], t.normal[2], 1);
                    auto interpolated_texcoords=interpolate(alpha, beta, gamma, t.tex_coords[0], t.tex_coords[1], t.tex_coords[2], 1);
                    auto interpolated_shadingcoords = interpolate(alpha, beta, gamma, view_pos[0], view_pos[1], view_pos[2],1);
                    fragment_shader_payload payload(interpolated_color, interpolated_normal.normalized(), interpolated_texcoords, texture ? &*texture : nullptr);
                    payload.view_pos = interpolated_shadingcoords;
                    auto pixel_color = fragment_shader(payload);
                    Vector2i nowpixel(x, y);
                    set_pixel(nowpixel, pixel_color);
                }
            }
        }
    }
    // TODO: From your HW3, get the triangle rasterization code.
    // TODO:从作业3,得到三角形光栅化代码
    // TODO: Inside your rasterization loop:
    // TODO:写入你的光栅化loop循环

    //    * v[i].w() is the vertex view space depth value z.
    //    * v[i].w()是顶点视图空间的深度值z

    //    * Z is interpolated view space depth for the current pixel
    //    * Z是当前像素的插值视图空间深度

    //    * zp is depth between zNear and zFar, used for z-buffer
    //    * zp是zNear和zFar之间的深度,用于z缓冲区

    // float Z = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
    // float zp = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
    // zp *= Z;

    // TODO: Interpolate the attributes:
    // TODO:插入属性:
    // auto interpolated_color 
    // auto interpolated_normal 
    // auto interpolated_texcoords 
    // auto interpolated_shadingcoords 

    // Use: fragment_shader_payload payload( interpolated_color, interpolated_normal.normalized(), interpolated_texcoords, texture ? &*texture : nullptr);
    // Use: payload.view_pos = interpolated_shadingcoords;
    // Use: Instead of passing the triangle's color directly to the frame buffer, pass the color to the shaders first to get the final color;
    // 用法:不要将三角形的颜色直接传递到帧缓冲区,而是首先将颜色传递给着色器以获得最终颜色;
    // Use: auto pixel_color = fragment_shader(payload);

 
}

2.

Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio, float zNear, float zFar)
{
    // TODO: Use the same projection matrix from the previous assignments
    Matrix4f projection = Matrix4f::Identity();
    Matrix4f persp;
    Matrix4f ortho1, ortho2;

    float r, l, t, b, n, f;
    float angle = eye_fov * MY_PI / 180.0 / 2;
    n = zNear;
    f = zFar;
    t = -tan(angle) * n;
    b = tan(angle) * n;
    r = t * aspect_ratio;
    l = -t * aspect_ratio;

    persp << n, 0, 0, 0,
        0, n, 0, 0,
        0, 0, n + f, -n * f,
        0, 0, 1, 0;

    ortho1 << 2 / (r - l), 0, 0, 0,
        0, 2 / (t - b), 0, 0,
        0, 0, 2 / (n - f), 0,
        0, 0, 0, 1;

    ortho2 << 1, 0, 0, -(r + l) / 2,
        0, 1, 0, -(t + b) / 2,
        0, 0, 1, -(n + f) / 2,
        0, 0, 0, 1;

    projection = ortho1 * ortho2 * persp * projection;
    return projection;

}

运行结果:1e3f31b25a8744b392599ca1335446ce.png

3.

Vector3f phong_fragment_shader(const fragment_shader_payload& payload)
{
    Vector3f ka = Vector3f(0.005, 0.005, 0.005);
    Vector3f kd = payload.color;
    Vector3f ks = Vector3f(0.7937, 0.7937, 0.7937);

    auto l1 = light{{20, 20, 20}, {500, 500, 500}};
    auto l2 = light{{-20, 20, 0}, {500, 500, 500}};

    vector<light> lights = {l1, l2};
    Vector3f amb_light_intensity{10, 10, 10};
    Vector3f eye_pos{0, 0, 10};

    float p = 150;

    Vector3f color = payload.color;
    Vector3f point = payload.view_pos;
    Vector3f normal = payload.normal;

    Vector3f result_color = {0, 0, 0};
    
    for (auto& light : lights)
    {
        // TODO: For each light source in the code, calculate what the *ambient*, *diffuse*, and *specular* 
        // components are. Then, accumulate that result on the *result_color* object.
        //TODO:对于代码中的每个光源,计算* ambient* 、* diffuse* 和* specular* 的值
        //然后在*result_color*对象上累积该结果。
        Vector3f light_intensity = light.intensity / (light.position - point).dot(light.position - point);//I/r^2
        Vector3f l = (light.position - point).normalized();//阳光入射角度
        Vector3f v = (eye_pos - point).normalized();//人视觉角度
        Vector3f h = (l + v).normalized();
        float ld_energy = l.dot(normal) > 0 ? l.dot(normal) : 0;//max(0,n·l)
        float ls_energy = pow((h.dot(normal) > 0 ? h.dot(normal) : 0), p);//max(0,n·h)^p
        Vector3f la = ka.cwiseProduct(amb_light_intensity);
        Vector3f ld = kd.cwiseProduct(light_intensity) * ld_energy;
        Vector3f ls = ks.cwiseProduct(light_intensity) * ls_energy;
        result_color += la + ld + ls;
    }

    return result_color * 255.f;
}

运行结果:256e9bd0f08d4c19a4eea8fc2db2fb78.png

 

4.

Vector3f texture_fragment_shader(const fragment_shader_payload& payload)
{
    Vector3f return_color = {0, 0, 0};
    if (payload.texture)
    {
        // TODO: Get the texture value at the texture coordinates of the current fragment
        //获取当前片段纹理坐标处的纹理值
        return_color = payload.texture->getColor(payload.tex_coords.x(),payload.tex_coords.y());
    }
    Vector3f texture_color;
    texture_color << return_color.x(), return_color.y(), return_color.z();

    Vector3f ka = Vector3f(0.005, 0.005, 0.005);
    Vector3f kd = texture_color / 255.f;
    Vector3f ks = Vector3f(0.7937, 0.7937, 0.7937);

    auto l1 = light{{20, 20, 20}, {500, 500, 500}};
    auto l2 = light{{-20, 20, 0}, {500, 500, 500}};

    vector<light> lights = {l1, l2};
    Vector3f amb_light_intensity{10, 10, 10};
    Vector3f eye_pos{0, 0, 10};

    float p = 150;

    Vector3f color = texture_color;
    Vector3f point = payload.view_pos;
    Vector3f normal = payload.normal;

    Vector3f result_color = {0, 0, 0};

    for (auto& light : lights)
    {
        // TODO: For each light source in the code, calculate what the *ambient*, *diffuse*, and *specular* 
        // components are. Then, accumulate that result on the *result_color* object.
//以下代码和phong没有区别
        Vector3f light_intensity = light.intensity / (light.position - point).dot(light.position - point);//I/r^2
        Vector3f l = (light.position - point).normalized();//阳光入射角度,标准向量
        Vector3f v = (eye_pos - point).normalized();//人视觉角度,标准向量
        Vector3f h = (l + v).normalized();
        float ld_energy = l.dot(normal) > 0.0 ? l.dot(normal) : 0.0;//max(0,n·l)
        float ls_energy = pow((h.dot(normal) > 0.0 ? h.dot(normal) : 0.0), p);//max(0,n·h)^p
        Vector3f la = ka.cwiseProduct(amb_light_intensity);
        Vector3f ld = kd.cwiseProduct(light_intensity) * ld_energy;
        Vector3f ls = ks.cwiseProduct(light_intensity) * ls_energy;
        result_color += la + ld + ls;
    }

    return result_color * 255.f;
}

运行结果:856b54dccb8d4e508b5180bd617ab5f4.png
5.

Vector3f bump_fragment_shader(const fragment_shader_payload& payload)
{

    Vector3f ka = Vector3f(0.005, 0.005, 0.005);
    Vector3f kd = payload.color;
    Vector3f ks = Vector3f(0.7937, 0.7937, 0.7937);

    auto l1 = light{ {20, 20, 20}, {500, 500, 500} };
    auto l2 = light{ {-20, 20, 0}, {500, 500, 500} };

    vector<light> lights = { l1, l2 };
    Vector3f amb_light_intensity{ 10, 10, 10 };
    Vector3f eye_pos{ 0, 0, 10 };

    float p = 150;

    Vector3f color = payload.color;
    Vector3f point = payload.view_pos;
    Vector3f normal = payload.normal;


    float kh = 0.2, kn = 0.1;

    // TODO: Implement bump mapping here
    //在此处实现bump贴图

    // Let n = normal = (x, y, z)
    float x = normal.x();
    float y = normal.y();
    float z = normal.z();
    // Vector t = (x*y/sqrt(x*x+z*z),sqrt(x*x+z*z),z*y/sqrt(x*x+z*z))
    Vector3f t(x * y / sqrt(x * x + z * z), sqrt(x * x + z * z), z * y / sqrt(x * x + z * z));
    // Vector b = n cross product t
    //b=n差积t
    Vector3f b = normal.cross(t);
    // Matrix TBN = [t b n]
    Matrix3f TBN;
    TBN << t.x(), b.x(), x,
        t.y(), b.y(), y,
        t.z(), b.z(), z;
    // dU = kh * kn * (h(u+1/w,v)-h(u,v))
    //bump mapping 部分的 h(u,v)=texture_color(u,v).norm, 其中 u,v 是 tex_coords, w,h 是 texture 的宽度与高度
    //实现 h(u+1/w,v) 的时候要写成 h(u+1.0/w,v)
    float u = payload.tex_coords.x();
    float v = payload.tex_coords.y();
    float w = payload.texture->width;
    float h = payload.texture->height;
    float dU = kh * kn * (payload.texture->getColor(u + 1.0 / w, v).norm() - payload.texture->getColor(u, v).norm());
    // dV = kh * kn * (h(u,v+1/h)-h(u,v))
    float dV = kh * kn * (payload.texture->getColor(u, v + 1.0 / h).norm() - payload.texture->getColor(u, v).norm());
    // Vector ln = (-dU, -dV, 1)
    Vector3f ln(-dU, -dV, 1.0);
    // Normal n = normalize(TBN * ln)
    normal = (TBN * ln).normalized();


    Vector3f result_color = {0, 0, 0};
    result_color = normal;

    return result_color * 255.f;
}

运行结果: 6a2384a4af224f27a399e02d6c2cfbc5.png

6.

Vector3f displacement_fragment_shader(const fragment_shader_payload& payload)
{
    
    Vector3f ka = Vector3f(0.005, 0.005, 0.005);
    Vector3f kd = payload.color;
    Vector3f ks = Vector3f(0.7937, 0.7937, 0.7937);

    auto l1 = light{{20, 20, 20}, {500, 500, 500}};
    auto l2 = light{{-20, 20, 0}, {500, 500, 500}};

    vector<light> lights = {l1, l2};
    Vector3f amb_light_intensity{10, 10, 10};
    Vector3f eye_pos{0, 0, 10};

    float p = 150;

    Vector3f color = payload.color; 
    Vector3f point = payload.view_pos;
    Vector3f normal = payload.normal;

    float kh = 0.2, kn = 0.1;
    
    // TODO: Implement displacement mapping here
    // Let n = normal = (x, y, z)
    float x = normal.x();
    float y = normal.y();
    float z = normal.z();
    // Vector t = (x*y/sqrt(x*x+z*z),sqrt(x*x+z*z),z*y/sqrt(x*x+z*z))
    Vector3f t(x * y / sqrt(x * x + z * z), sqrt(x * x + z * z), z * y / sqrt(x * x + z * z));
    // Vector b = n cross product t
    Vector3f b = normal.cross(t);
    // Matrix TBN = [t b n]
    Matrix3f TBN;
    TBN << t.x(), b.x(), x,
        t.y(), b.y(), y,
        t.z(), b.z(), z;
    // dU = kh * kn * (h(u+1/w,v)-h(u,v))
    float u = payload.tex_coords.x();
    float v = payload.tex_coords.y();
    float w = payload.texture->width;
    float h = payload.texture->height;
    float dU = kh * kn * (payload.texture->getColor(u + 1.0 / w, v).norm() - payload.texture->getColor(u, v).norm());
    // dV = kh * kn * (h(u,v+1/h)-h(u,v))
    float dV = kh * kn * (payload.texture->getColor(u, v + 1 / h).norm() - payload.texture->getColor(u, v).norm());
    // Vector ln = (-dU, -dV, 1)
    Vector3f ln(-dU, -dV, 1);
    // Position p = p + kn * n * h(u,v)
    //---------------------唯一需要修改的代码-----------------------------
    point += kn * normal * payload.texture->getColor(u, v).norm();
    // Normal n = normalize(TBN * ln)
    normal = (TBN * ln).normalized();


    Vector3f result_color = {0, 0, 0};

    for (auto& light : lights)
    {
        // TODO: For each light source in the code, calculate what the *ambient*, *diffuse*, and *specular* 
        // components are. Then, accumulate that result on the *result_color* object.
        Vector3f light_intensity = light.intensity / (light.position - point).dot(light.position - point);//I/r^2
        Vector3f l = (light.position - point).normalized();//阳光入射角度,标准向量
        Vector3f v = (eye_pos - point).normalized();//人视觉角度,标准向量
        Vector3f h = (l + v).normalized();
        float ld_energy = l.dot(normal) > 0.0 ? l.dot(normal) : 0.0;//max(0,n·l)
        float ls_energy = pow((h.dot(normal) > 0.0 ? h.dot(normal) : 0.0), p);//max(0,n·h)^p
        Vector3f la = ka.cwiseProduct(amb_light_intensity);
        Vector3f ld = kd.cwiseProduct(light_intensity) * ld_energy;
        Vector3f ls = ks.cwiseProduct(light_intensity) * ls_energy;
        result_color += la + ld + ls;

    }

    return result_color * 255.f;
}

运行结果 :034cf0313652463aa587dcac8d19a8ef.png

 

 

存在问题:

1.对于bump虽然按照老师的注释写下来了,但是还是不太能理解。希望后期可以再看看

2.这里的weight不知道为什么是1,但是根据我的运行,会存在溢出,必须修改老师给好的框架,我认为这里应该还有可以思考的地方。

static Vector2f interpolate(float alpha, float beta, float gamma, const Vector2f& vert1, const Vector2f& vert2, const Vector2f& vert3, float weight)

 3.光线的平方必须要点乘,而不能先cwiseProduct求平方再求长度。写成这样的话,会比要求得到的图形亮上一点。

Vector3f light_intensity = light.intensity / (light.position - point).cwiseProduct(light.position - point).norm();

594239c23409467696486ea116a5e5a5.png

左边是老师要求的。右边是我得到的错误结果。

4.

auto [alpha, beta, gamma] = computeBarycentric2D(x+0.5, y+0.5, t.v);

最开始老师给的代码一直有问题,只能自己重写:

float alpha, beta, gamma;
std::tuple<float, float, float> angle(alpha, beta, gamma);
angle = computeBarycentric2D(x+0.5, y+0.5, t.v);

但是会导致法向量模型有问题,只能又改回老师的代码(这时候又没问题了。可能是c++17的原因,之前用的是老版本)。自己重写的会导致结果变为:

c26f9357254e4dfb86212e366d120f61.png

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

games101 作业3 的相关文章

  • 求旋转后的坐标

    坐标点target 中心点center 角度angle 旋转后坐标 function getRotatePoint targetX targetY centerX centerY angle const rotation angle Mat
  • networkx画图(番外)——(1)自定义节点布局

    networkx画图 番外 1 自定义节点布局 networkx虽然非常方便 但在一些超大规模的图数据上 依然显得吃力 所以大多数时候 它仅仅是被用来做一些实例性的分析和可视化展示的 这需要学会如何灵活的画图 最重要的就是布局 即每个节点在
  • 计算机视觉 相机标定

    目录 一 相机标定原理 1 相机标定简介 2 求解原理 2 1 针孔相机模型 2 2 畸变现象 2 3 像主点偏移 2 4 单应性矩阵H 二 相机标定策略 2 1 相关策略 2 2 棋盘格标定 三 实验内容 1 实验数据 2 实验代码 3
  • 蓝桥杯算法提高VIP-队列操作

    题目 题目链接 题解 模拟队列 代码 include
  • 【配置文档】配置使用CGAL库的经验分享

    诸多经验贴都建议参考CGAL官方网站的步骤一步一步配置 因为我懒得看英文所以找的都是中文博客和问答 结果走了不少弯路 这里开一篇经验贴 记录错误也方便以后的查阅 本文是基于VS2017的配置和使用 这里是CGAL的使用手册 文章目录 一 需
  • 人类高质量网格重建算法

    通常对于几何曲面的绘制采用采样描点的方式 比如球的方程为 对于这个方程可以将其改为参数方程 然后对与进行离散化 从而得到一系列的离散点 下面是c 的代码生成一个球 class Sphere public Mesh public Sphere
  • 【Blender】贝塞尔曲线图形原理和公式推导

    Blender 贝塞尔曲线图形原理和公式推导 什么是贝塞尔曲线 贝塞尔曲线 英文名Bezier Curve 是计算机图形学非常重要的一种曲线 它可以将若干的点 用一条平滑自然的曲线来连接起来 比如我们在地图库中绘制用户行走轨迹时 如果用折线
  • PCL——VTK读取、保存.ply模型数据

    目录 一 读取 ply文件 1 代码示例 2 结果展示 一 保存 ply文件 1 代码示例 2 结果展示 一 读取 ply文件 ReadPLY 是VTK内置的mesh模型读取函数 该函数仅支持 ply格式的mesh网格数据不支持读取 ply
  • Python123 练习5

    文章目录 1 一元二次方程求根 2 百钱买百鸡 3 鸡兔同笼 4 最大公约数和最小公倍数 5 判断三角形并计算面积 6 判断IP地址合法性 7 回文素数 8 反素数 9 今天是第几天 10 提取首字符 11 判断火车票座位 如果文章内容或代
  • 14.1 矩阵幂级数

    文章目录 矩阵的幂 矩阵幂的极限 谱半径与范数 矩阵幂级数 矩阵的幂 现在讨论下矩阵的n次方的问题 比如下面的矩阵 A 1
  • 2020年蓝桥杯省赛-平面分割

    题目 题目链接 题解 计算几何 整理公式得 m m 1 1
  • 情人节用Python画玫瑰花

    用Python turtle 绘制的玫瑰花 效果图 import turtle import time turtle penup turtle setup 1100 1000 turtle hideturtle turtle speed 1
  • 代数余子式的几何意义,点积和叉乘的几何意义

    1 点乘的几何意义 a b c d e f ad be cf 结果是一个标量 也可以写为 a b a b cos 以下说明点乘的几何意义 就是一个向量在另一个单位向量 如果另一个向量是单位向量 上的投影长度 a b b a cos a b
  • geojson 格式说明(格式详解)

    1 简介 GeoJSON是一种对地理数据结构进行编码的格式 GeoJSON对象可以表示几何信息 要素或者要素集合 GeoJSON支持下面几何类型 Point LineString Polygon MultiPoint MultiLineSt
  • 时域采样,频域为什么周期延拓了

    频域周期延拓只是表面现象 其实质是不同的信号采样后的像可能相同 不可区分 如果硬要做实验 还是要有一定的编程基础 起码要整一个声音出来 让你听一听 可是你要重复这一实验可能又太难了 所以我还是讲一讲简单的数学原理 并用简单的三角函数及程序验
  • games101 作业3

    遇到的问题 1 项目才打开时无法运行 解决方法 切换成c 17 解决方法引用 Games101 作业3 环境问题 知乎 注 知乎里面的关于越界限制的控制不适用 虽然可以解决部分作业的问题 但是在bump里面依然会出现越界错误 应该用以下大佬
  • 计算机图形学GAMES101(十五)光线追踪(蒙特卡洛积分与路径追踪)

    本节涉及内容 蒙特卡罗积分 路径追踪 蒙特卡罗积分 蒙特卡罗积分的核心思想还是求一个不规则图形的面积 它的做法是 首先在a和b之间找一个值xi然后求f x 接着以f x 为高 ab为宽求矩形的面积 最后将所有的值求平均 当采样数量xi趋于无
  • 最小二乘法求解圆方程圆形及半径

    ci最小二乘法定义 摘抄于百度百科 基本思路 摘抄于百度百科 简单的来说 最小二乘法为一类线性算法 将需要求解的系数当作未知数 f x 与x当作已知数 通过多组对应关系求得系数的方法 所以 最小二乘法仅适合系数为一次项方程式 例如 k与b作
  • 高等数学——驻点,拐点,极值点

    一 定义不同 1 极值点 若f a 是函数f x 的极大值或极小值 则a为函数f x 的极值点 极大值点与极小值点统称为极值点 极值点是函数图像的某段子区间内上极大值或者极小值点的横坐标 极值点出现在函数的驻点 导数为0的点 或不可导点处
  • 刚体动力学

    文章目录 刚体状态 将某个物体从局部坐标系变化到全局坐标系 对时间求导 对矩阵求导 惯性 刚体属性 1 质心 计算方法 体素法 直接计算法 四面体体积 四面体的中心 2 惯性张量 世界坐标系中的惯性变量 刚体运动 力矩 刚体的固定属性 当前

随机推荐

  • Blender 骨骼子父级关系链接

    一 骨骼子父集关系链接 操作顺序 1 选中物体 2 选中骨骼 3 Ctrl P根据个人需求选择 多数情况会选择自动权重 如果选择顺序不同 Ctrl P出现的界面就不会显示权重选择 二 骨骼被物件遮挡 选中骨骼 在下图中的界面里 勾选在前面即
  • 【51单片机】:定时器的详解(包括对单片机定时解释、各类定时方式,以及中断方式)

    学习目标 51定时 计数器的详解 码字不易 如有帮助请收藏 点赞哦 学习内容 背景知识 了解一下对以后学习有帮助 前提 首先我们知道51单片机内部有21 26个特殊功能寄存器 P x口寄存器 P0 P1 P2 P3 数据指针寄存器 DP0H
  • STM32 GPIO 详解

    0 实验平台 基于STM32F407ZG 1 GPIO 简介 1 1 简介 GPIO全称 General Purpose Input Output 即通用输入输出端口 一般用来采集外部器件的信息或者控制外部器件工作 即输入输出 1 2 ST
  • 前端系列——jquery.i18n.properties前端国际化解决方案“填坑日记”

    前言 最近 新的平台还没有开发完成 原来的老项目又提出了新的需求 系统国际化 如果是前后端完全分离的开发模式 要做国际化 真的太简单了 有现成的解决方案 基于Node构建的时下热门的任何一种技术选型都有成熟的方案 比如 vue vue i1
  • delphi 通过TNetHTTPClient解析抖音无水印高清视频原理及解决X-Bogus签名验证2023-5-1

    一 杂谈 最近有很多热心网友反馈抖音去水印又不行了 之前是时不时被blocked 现在直接连内容都没有了 返回直接就是空了 我们今天简要给大家分析一下请求过程 附上delphi 源码 及生成签名验证 成功请求到json数据的解决方法 二 请
  • 损失函数:IoU、GIoU、DIoU、CIoU、EIoU、alpha IoU、SIoU、WIoU超详细精讲及Pytorch实现

    前言 损失函数是用来评价模型的预测值和真实值不一样的程度 损失函数越小 通常模型的性能越好 不同的模型用的损失函数一般也不一样 损失函数的使用主要是在模型的训练阶段 如果我们想让预测值无限接近于真实值 就需要将损失值降到最低 在这个过程中就
  • 苹果官网序列号查询

    苹果官网 https checkcoverage apple com cn zh locale zh CN 官换机要怎么鉴别是正品新机 https www zhihu com question 44779845
  • 基于C++的OpenCV项目实战——零部件的自动光学检测

    基于C 的OpenCV项目实战 零部件的自动光学检测 一 背景 首先任务背景是AOI 自动光学检测 最重要的目的在于 将前景和物体进行分割与分类 场景示意图 需要注意 在螺母的传送带上 需要有前光和背光 给物体打光才能够拍摄清晰的图像 二
  • LeetCode4. 寻找两个正序数组的中位数

    题意 给定长度为 n n n的数组 A A A和长度为 m m m的数组
  • 小P学区块链(一):区块链到底是什么?该如何去学习

    2018年3月25日 CSDN 副总裁孟岩老师在北京联合大学商务学院举办了一场关于区块链及智能合约相关的公开课 在课程的三个小时里 受益匪浅 我会对课程的理解和对区块链及智能合约的概念做一个总结 同样我也会继续学习这方面的知识 将定期更新相
  • sonarqube主要功能概览

    sonarqube质量标准 sonarqube通过可靠性 安全性 安全复审 可维护性 覆盖率 重复度等方面来评价代码质量 分别使用bugs 漏洞等指标 如图 有项目状态为正常 有项目状态为错误 点进项目可以看具体 可以对问题进行分配 处理
  • 【剑指Offer】(字符串)左旋转字符串(翻转操作)

    题目链接 https www nowcoder com practice 12d959b108cb42b1ab72cef4d36af5ec tpId 13 tqId 11196 tPage 1 rp 1 ru ta coding inter
  • python游戏编程培训

    准备好了吗 我们即将开始激动人心的游戏编程之旅 或许你之前学习过一点编程 但若是你从没接触过游戏编程 那么你仍然会对游戏程序的运行感到不解 游戏程序不像计算一个公式或谜题 得到答案之后程序就结束了 游戏程序一直是处于运行中的 只要你不主动退
  • 递归行为时间复杂度计算:master公式

    master公式 T N a T N b O N d 公式解释 N是初始问题的负责度 a是次数的意思 也就是调用相同规模的递归次数 b是递归的划分 也就是将原问题划分成相同规模的b份 O N d d是除去递归代码外的其他运算的时间复杂度 例
  • python爬虫系列6--模拟登陆相关

    方式原理 爬虫爬取数据时 有些数据并不能让游客访问到 这时候就需要进行登录 再爬取数据 登录后再爬取的手段很多 但核心都是通过cookie的方式来记录身份信息 因此模拟登录的核心在于对cookie的使用 参考链接 https www cnb
  • Android Kotlin的学习

    1 kotlin简介 Kotlin是一种在Java虚拟机上运行的静态类型编程语言 它也可以被编译成为JavaScript源代码 它主要是由俄罗斯圣彼得堡的JetBrains开发团队所发展出来的编程语言 其名称来自于圣彼得堡附近的科特林岛 3
  • 【CLIP速读篇】Contrastive Language-Image Pretraining

    CLIP速读篇 Contrastive Language Image Pretraining 0 前言 Abstract 1 Introduction and Motivating Work 2 Approach 2 1 Natural L
  • 从元宇宙角度看社交出海产品新体验

    提到社交产品 不可避免的会涉及元宇宙方向 那么元宇宙距离落地还有哪些问题 解决这些问题是否会是新的产品机会 社交作为元宇宙赛道的细分领域之一 如何在未来几年向元宇宙产品发展 打造产品新体验 实现用户增长 本文整理自拍乐云行业解决方案专家奚振
  • 《普林斯顿微积分》读书笔记

    写在前面 并不完整 只有零散的记忆 二 三刷的时候再补充吧 一些初等函数的导数 例如 x n n x n 1 sin x cos x 积分等于反导数 其他 待补充
  • games101 作业3

    遇到的问题 1 项目才打开时无法运行 解决方法 切换成c 17 解决方法引用 Games101 作业3 环境问题 知乎 注 知乎里面的关于越界限制的控制不适用 虽然可以解决部分作业的问题 但是在bump里面依然会出现越界错误 应该用以下大佬