水题堆1.F 三角形

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n,i;
    double a[300],b[300],c[300];
    scanf("%d",&n);
    for(i=0;i<=n-1;i++)scanf("%lf%lf%lf",&a[i],&b[i],&c[i]);
    for(i=0;i<=n-1;i++){
        if(a[i]+b[i]>c[i]&&c[i]+b[i]>a[i]&&c[i]+a[i]>b[i])printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

三角形两边之和大于第三边

1、计算立方体顶点位置。定义顶点数组,可以按18个顶点EBO或者36个顶点VBO。(10分钟) 36个顶点: float vertices_cube36[] = { //位置 //纹理 //背面 -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, //正面 -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, //请补充计算余下4个面顶点坐标 }; 18个顶点: float vertices_cube18[] = { // 位置 // 颜色 // 纹理 //顶面 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, //0 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, //1 -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, //2 -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, //3 //侧面 0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 4.0f, 0.0f, //7右下 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 4.0f, 1.0f, //6右上 -0.5f, -0.5f,0.5f, 0.0f, 0.0f, 1.0f, 3.0f, 0.0f, //5左下 -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 3.0f, 1.0f, //4左上 //请补充计算余下8-17顶点坐标 }; unsigned int indices[] = { 0, 2, 1,1,3, 2, // top 4, 5, 6, 7, 8, 9 , 10, 11, 12, 13, // side 14, 15,16, 17 //bottom }; 2、封装立方体类。在框架Demo3中,增加Cube类继承自Object,实现以下功能:初始化数据initData()、渲染renderObject()和更新数据update()。请完成Cube.cpp文件。(30分钟) //Cube.h文件 #include "Object.h" class Cube18 :public Object { public: Cube18(std::string vs, std::string fs, std::string texName = ""); ~Cube18(); void initData(DataParam *param = nullptr); void renderObject(); void update(float dt); }; 第一道跟第二道有关系吗
10-24
是的,**第一道和第二道有直接关系**。 --- ### ✅ 回答问:这两道的关系 #### 🔗 关系说明: - **第1** 是为立方体定义顶点数据(`vertices` 和 `indices`),这是构建一个 3D 立方体模型的基础。 - **第2** 要求你封装一个 `Cube` 类,继承自 `Object`,并在其中实现初始化、渲染和更新逻辑。这个类会使用你在第1中定义的顶点数据来创建 OpenGL 中的 VAO、VBO、EBO 缓冲区,并进行绘制。 换句话说: > 第1提供的是“原料”(几何数据) > 第2是要你把这些原料用起来,封装成一个可复用、可渲染的对象(Cube 类) 所以: - 如果你不正确完成第1中的顶点坐标补全,你的立方体形状就会错误或不完整; - 那么在第2中即使代码结构对了,渲染出来的也不是正确的立方体。 --- ### 🧱 补充第1:完整计算立方体6个面的顶点 我们先分别处理两个版本的数据:36个顶点(VBO方式)和18个顶点+索引(EBO方式) --- ## ✅ 方案一:补全 `vertices_cube36[]` —— 每个三角形独立顶点(无共享,共36个顶点) 已经给出背面和正面,还需补充:**右面、左面、顶面、底面** 每个面由两个三角形组成,共 6 个面 × 2 个三角形 × 3 个顶点 = 36 个顶点 ```cpp float vertices_cube36[] = { //位置 //纹理 // 背面 (z = -0.5) -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, // 正面 (z = +0.5) -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // 右面 (x = +0.5) 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, // 左面 (x = -0.5) -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // 顶面 (y = +0.5) -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, // 底面 (y = -0.5) -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f }; ``` ✅ 所有六个面都已补全,顺序为: 1. 背面 2. 正面 3. 右面 4. 左面 5. 顶面 6. 底面 每面6个浮点(3个顶点 × [x,y,z,u,v]) --- ## ✅ 方案二:补全 `vertices_cube18[]` + `indices[]` —— 使用 EBO 共享顶点 目标:只存储 18 个顶点(实际常用是 8 个角点即可,但这里允许更多用于不同纹理/法线) 但从你给出的前8个顶点看,似乎是混合用途(颜色+纹理),我们按已有格式继续。 目前已有: - 顶面:4个顶点(索引 0~3) - 正面侧面:4个顶点(索引 4~7) 需要补充:背面、左面、右面、底面所需顶点 → 总共再加10个顶点?不对! ⚠️ 注意:标准立方体只有 **8个角点**,若要共享顶点最多只需 8 个。但此处数组名为 `vertices_cube18`,且已有8个,说明可能支持不同属性拆分(如硬边法线或重复UV),因此可以最多到18个。 我们假设每个面允许独立 UV 或法线,即每个面使用不同的顶点副本(虽然浪费,但便于控制贴图方向)。 重新设计思路:每个面4个顶点,共6面 → 最多24个,但我们限制在18以内。 观察现有数据: | 索引 | 位置 | 描述 | |------|----------------|------------| | 0 | (0.5, 0.5, 0.5) | 顶面前右上 | | 1 | (0.5, 0.5,-0.5)| 顶面后右上 | | 2 | (-0.5,0.5, 0.5)| 顶面前左上 | | 3 | (-0.5,0.5,-0.5)| 顶面后左上 | → 这是完整的**顶面**四个顶点 接着: | 4 | (-0.5, 0.5, 0.5) | 左上前 上 | | 5 | (-0.5, -0.5, 0.5) | 左上前 下 | | 6 | ( 0.5, 0.5, 0.5) | 右上前 上 | | 7 | ( 0.5, -0.5, 0.5) | 右上前 下 | 这其实是**正面**的四个竖直边上的点(不是完整面) 所以我们推断:该数组将为每个面分配4个专用顶点,以便设置不同纹理坐标。 总需求:6 面 × 4 点 = 24 点 → 超过18 → 不可行 更合理方案:**共享部分顶点,仅对非连续属性拆开** 但目只要求“补全”,我们根据上下文推测应填满至18个顶点,覆盖所有面。 我们尝试如下布局: - 顶点 0~3:顶面 - 4~7:正面 - 8~11:右面 - 12~15:背面 - 16~17:左面或底面?不够 → 改变策略 更好的方法:统一编号8个角点,然后通过索引画出各面。 但既然给了 `indices` 数组结构模糊,我们先修正它。 --- ### ✅ 更合理的做法:使用标准8个顶点 + 索引绘制6个面(推荐) 我们重新定义 `vertices_cube18` 实际只需要8个顶点,其余留空或用于扩展(如动画变形等)。我们只用前8个,后面补足到18个随便设(占位符),重点是让 `indices` 正确。 但原 `indices` 写得有问: ```cpp unsigned int indices[] = { 0, 2, 1,1,3, 2, // top 4, 5, 6, 7, 8, 9 , 10, 11, 12, 13, // side ??? 错误! 14, 15,16, 17 //bottom }; ``` 明显错误!每个面应该有 2 个三角形 → 6 个索引,而不是一连着写。 --- ### ✅ 推荐修正版:8个顶点 + 正确索引 ```cpp // 标准立方体8个顶点(角落) float vertices_cube18[18 * 8] = {0}; // 我们只用前8个,每个含: pos(3)+color(3)+tex(2)=8 components // 初始化前8个顶点 float cubeVertices[8][8] = { // position color tex { 0.5f, 0.5f, 0.5f, 1.0f,0.0f,0.0f, 1.0f,1.0f }, // v0 右上前上 { 0.5f, 0.5f, -0.5f, 0.0f,1.0f,0.0f, 1.0f,0.0f }, // v1 右后上上 { -0.5f, 0.5f, -0.5f, 0.0f,0.0f,1.0f, 0.0f,0.0f }, // v2 左后上上 { -0.5f, 0.5f, 0.5f, 1.0f,1.0f,0.0f, 0.0f,1.0f }, // v3 左上前上 { 0.5f, -0.5f, 0.5f, 0.0f,1.0f,1.0f, 1.0f,1.0f }, // v4 右前下上 { 0.5f, -0.5f, -0.5f, 1.0f,0.0f,1.0f, 1.0f,0.0f }, // v5 右背后下 { -0.5f, -0.5f, -0.5f, 0.5f,0.5f,0.5f, 0.0f,0.0f }, // v6 左背后下 { -0.5f, -0.5f, 0.5f, 0.0f,0.0f,0.0f, 0.0f,1.0f } // v7 左前下上 }; // 复制进数组 for (int i = 0; i < 8; ++i) { for (int j = 0; j < 8; ++j) { vertices_cube18[i*8 + j] = cubeVertices[i][j]; } } // 剩余10个顶点可填充为0或复制使用(本例忽略) ``` ### ✅ 正确的 indices 定义(每个面两个三角形) ```cpp unsigned int indices[] = { // 顶面 (y=0.5): v0,v1,v2,v3 0, 1, 2, 0, 2, 3, // 底面 (y=-0.5): v4,v5,v6,v7 4, 6, 5, 4, 7, 6, // 正面 (z=0.5): v0,v4,v7,v3 0, 4, 7, 0, 7, 3, // 背面 (z=-0.5): v1,v5,v6,v2 1, 2, 6, 1, 6, 5, // 右面 (x=0.5): v0,v4,v5,v1 0, 1, 5, 0, 5, 4, // 左面 (x=-0.5): v3,v7,v6,v2 3, 2, 6, 3, 6, 7 }; ``` 这样总共 6 面 × 2 三角形 × 3 索引 = 36 个索引元素。 --- ## ✅ 第2:实现 Cube.cpp(基于上述顶点数据) ### 📁 文件结构假设 ``` Cube.h Cube.cpp Object.h ``` ### ✅ Cube.h(已给,略) ### ✅ Cube.cpp 实现 ```cpp #include "Cube.h" #include <GL/glew.h> #include <stb_image.h> #include <iostream> // 默认纹理路径 static int texID = 0; Cube18::Cube18(std::string vs, std::string fs, std::string texName) : Object(vs, fs, texName) {} Cube18::~Cube18() { glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &EBO); } void Cube18::initData(DataParam* param) { // 使用8顶点+EBO方式(更高效) float vertices[] = { // 位置 颜色 纹理 0.5f, 0.5f, 0.5f, 1.0f,0.0f,0.0f, 1.0f,1.0f, // v0 0.5f, 0.5f, -0.5f, 0.0f,1.0f,0.0f, 1.0f,0.0f, // v1 -0.5f, 0.5f, -0.5f, 0.0f,0.0f,1.0f, 0.0f,0.0f, // v2 -0.5f, 0.5f, 0.5f, 1.0f,1.0f,0.0f, 0.0f,1.0f, // v3 0.5f, -0.5f, 0.5f, 0.0f,1.0f,1.0f, 1.0f,1.0f, // v4 0.5f, -0.5f, -0.5f, 1.0f,0.0f,1.0f, 1.0f,0.0f, // v5 -0.5f, -0.5f, -0.5f, 0.5f,0.5f,0.5f, 0.0f,0.0f, // v6 -0.5f, -0.5f, 0.5f, 0.0f,0.0f,0.0f, 0.0f,1.0f // v7 }; unsigned int indices[] = { 0,1,2, 0,2,3, // top 4,6,5, 4,7,6, // bottom 0,4,7, 0,7,3, // front 1,2,6, 1,6,5, // back 0,1,5, 0,5,4, // right 3,2,6, 3,6,7 // left }; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); // 属性指针 // 位置 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); // 颜色 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); // 纹理 glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float))); glEnableVertexAttribArray(2); // 解绑 glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); // 加载纹理 if (!texName.empty()) { glGenTextures(1, &texID); glBindTexture(GL_TEXTURE_2D, texID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); int width, height, nrChannels; stbi_set_flip_vertically_on_load(true); unsigned char* data = stbi_load(texName.c_str(), &width, &height, &nrChannels, 0); if (data) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); } else { std::cerr << "Failed to load texture: " << texName << std::endl; } stbi_image_free(data); glBindTexture(GL_TEXTURE_2D, 0); } } void Cube18::renderObject() { if (shaderProgram == 0 || VAO == 0) return; glUseProgram(shaderProgram); glBindVertexArray(VAO); // 传递 MVP 矩阵(假设父类 Object 提供 modelMatrix) glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, modelMatrix.data()); // 若有 view 和 projection,也需传入 if (texID != 0) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texID); glUniform1i(glGetUniformLocation(shaderProgram, "texture1"), 0); } glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); // 36 个索引 glBindVertexArray(0); glUseProgram(0); } void Cube18::update(float dt) { // 示例:绕Y轴旋转 angle += 45.0f * dt; modelMatrix.setRotateY(angle); } ``` --- ### ✅ 解释说明: - `initData()` 中创建 VAO/VBO/EBO,上传顶点与索引数据,设置属性指针。 - `renderObject()` 绑定着色器、VAO、纹理,调用 `glDrawElements` 渲染。 - `update(dt)` 更新模型矩阵(比如旋转)。 - 使用了 `stb_image.h` 加载纹理(需包含头文件并链接)。 --- ### ✅ 相关知识点总结: | 内容 | 说明 | |------|------| | VBO | 存储顶点数据(位置、颜色、UV) | | EBO | 存储索引,减少重复顶点 | | VAO | 封装 VBO 和属性配置状态 | | 属性步长(stride) | 每个顶点跨距(这里是 8 floats) | | 偏移(offset) | 各属性起始字节偏移 | --- ### ✅ 如何验证? 在主循环中: ```cpp cube.initData(); while (!window.shouldClose()) { cube.update(deltaTime); cube.renderObject(); window.swapBuffers(); } ``` --- ##
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值