zoukankan      html  css  js  c++  java
  • CG 中点法画直线

    1. ((x_i,y_i) ightarrow (x_{i+1},y_{i+1}))

    根据可能所取点间的中点M与直线的位置
    构造判别式:(d = F(M) = F(x_{i+1}, y_{i,r}+0.5))
    由d的正和负可判定下一个像素。 其中 (p(x_i , y_{i,r}))为当前点坐标
    d < 0, 取NE;否则取E

    2.如何再确定下一个像素((x_{i+2},?))

    1) 若(d≥0), 取正右方像素E, 则判定再下一个像素的d为(d_1=F(x_i+2, y_{i,r}+0.5)=a(x_{i+2})+b(y_{i,r}+0.5)+c=d+a),d的增量是a
    2) 若d<0, 取右上方像素NE, 则判定再下一个像素的d为(d2=F(x_i+2, y_{i,r}+1.5)=d+a+b),d的增量为a+b

    3.增量d的初始值

    (d_0=F(x_0+1, y_0+0.5)=F(x_0, y_0)+a+0.5b=a + 0.5b)

    4.增量d的递推公式

    [d_0=a+0.5b \ d_i+1 = left{ egin{array}{lr} d_i+a & d_i>0\ d_i+a+b & d_ileq0 end{array} ight. ]

    2d代替d

    [d_0=2a+b\ d_i+1 = left{ egin{array}{lr} d_i+2a & d_i>0\ d_i+2a+2b & d_ileq0 end{array} ight. ]

    5.其他几种情况

    [0 leq m leq 1\ d_0=2a+b \ d_{i+1} = left{ egin{array}{lr} d_i+2a & d_i>0\ d_i+2a+2b & d_ileq0 end{array} ight. ]

    [ m > 1 \ d_0=a+2b \ d_{i+1} = left{ egin{array}{lr} d_i+2a+2b & d_i>0\ d_i+2b & d_ileq0 end{array} ight. ]

    [-1 leq m leq 0 \ d_0=2a-b \ d_{i+1} = left{ egin{array}{lr} d_i+2a-2b & d_i>0\ d_i+2a & d_ileq0 end{array} ight. ]

    [m<- 1 \ d_0=a-2b \ d_{i+1} = left{ egin{array}{lr} d_i-2b & d_i>0\ d_i+2a-2b & d_ileq0 end{array} ight. ]

    #include <iostream>
    
    // GLEW
    #define GLEW_STATIC
    #include <GL/glew.h>
    
    // GLFW
    #include <GLFW/glfw3.h>
    using namespace std;
    
    // Function prototypes
    void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
    
    // Window dimensions
    const GLuint WIDTH = 800, HEIGHT = 800;
    
    // Shaders
    const GLchar* vertexShaderSource = "#version 330 core
    "
    "layout (location = 0) in vec3 position;
    "
    "void main()
    "
    "{
    "
    "gl_Position = vec4(position.x, position.y, position.z, 1.0);
    "
    "}";
    const GLchar* fragmentShaderSource = "#version 330 core
    "
    "out vec4 color;
    "
    "void main()
    "
    "{
    "
    "color = vec4(128.0/255.0f, 1.0f, 28*6.0/255.0f, 1.0f);
    "
    "}
    ";
    
    GLint tot = 0;
    GLfloat vertices[100000];
    void MidpointLine(GLint x0, GLint y0, GLint x1, GLint y1);
    // The MAIN function, from here we start the application and run the game loop
    int main()
    {
        // Init GLFW
        glfwInit();
        // Set all the required options for GLFW
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    
        // Create a GLFWwindow object that we can use for GLFW's functions
        GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);
        glfwMakeContextCurrent(window);
    
        // Set the required callback functions
        glfwSetKeyCallback(window, key_callback);
    
        // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
        glewExperimental = GL_TRUE;
        // Initialize GLEW to setup the OpenGL Function pointers
        glewInit();
    
        // Define the viewport dimensions
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        glViewport(0, 0, width, height);
    
    
        // Build and compile our shader program
        // Vertex shader
        GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
        glCompileShader(vertexShader);
        // Check for compile time errors
        GLint success;
        GLchar infoLog[512];
        glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
    " << infoLog << std::endl;
        }
        // Fragment shader
        GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
        glCompileShader(fragmentShader);
        // Check for compile time errors
        glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED
    " << infoLog << std::endl;
        }
        // Link shaders
        GLuint shaderProgram = glCreateProgram();
        glAttachShader(shaderProgram, vertexShader);
        glAttachShader(shaderProgram, fragmentShader);
        glLinkProgram(shaderProgram);
        // Check for linking errors
        glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
        if (!success) {
            glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED
    " << infoLog << std::endl;
        }
        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);
    
    
        // Set up vertex data (and buffer(s)) and attribute pointers
        MidpointLine(0, 500, 0, -500);
        MidpointLine(-500, -500, 500, 700);
        MidpointLine(-500, 500, 500, -700);
        MidpointLine(-500, 200, 500, -300);
        GLuint VBO, VAO;
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
        glBindVertexArray(VAO);
    
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
        glEnableVertexAttribArray(0);
    
        glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind
    
        glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs)
    
        // Game loop
        while (!glfwWindowShouldClose(window))
        {
            // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions
            glfwPollEvents();
    
            // Render
            // Clear the colorbuffer
            glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
    
            // Draw our first triangle
            glUseProgram(shaderProgram);
            glBindVertexArray(VAO);
            glDrawArrays(GL_POINTS, 0, tot);
            glBindVertexArray(0);
    
            // Swap the screen buffers
            glfwSwapBuffers(window);
        }
        // Properly de-allocate all resources once they've outlived their purpose
        glDeleteVertexArrays(1, &VAO);
        glDeleteBuffers(1, &VBO);
        // Terminate GLFW, clearing any resources allocated by GLFW.
        glfwTerminate();
        return 0;
    }
    
    // Is called whenever a key is pressed/released via GLFW
    void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
    {
        if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
            glfwSetWindowShouldClose(window, GL_TRUE);
    }
    void addPoint(GLint x, GLint y, GLint z)
    {
        vertices[tot++] = 1.0 * x / WIDTH;
        vertices[tot++] = 1.0 * y / HEIGHT;
        vertices[tot++] = z;
    }
    
    void MidpointLine(GLint x0, GLint y0, GLint x1, GLint y1)
    {
        GLint a, b, d1, d2, d, x, y;
        GLfloat m;
        if (x1 < x0) { swap(x0, x1); swap(y0, y1);}
        a = y0 - y1, b = x1 - x0;
        if (b == 0) m = -1 * a * 100;
        else m = (GLfloat)a / (x0 - x1); 
        x = x0, y = y0;
        addPoint(x, y, 0);
    
        if (m >= 0 && m <= 1)
        {
            d = 2 * a + b; d1 = 2 * a; d2 = 2 * (a + b);
            while (x < x1)
            {
                if (d <= 0) { y++; d += d2; }
                else d += d1;
                x++;
                addPoint(x, y, 0);
            }
        }
        else if (m > 1)
        {
            d = a + 2 * b; d1 = 2 * (a + b); d2 = 2 * b;
            while (y < y1)
            {
                if (d > 0) { x++; d += d1; }
                else d += d2;
                y++;
                addPoint(x, y, 0);
            }
        }
        else if (m >= -1 && m <= 0)
        {
            d = 2 * a - b; d1 = 2 * a - 2 * b; d2 = 2 * a;
            while (x < x1)
            {
                if (d > 0) { y--; d += d1; }
                else d += d2;
                x++;
                addPoint(x, y, 0);
            }
        }
        else
        {
            d = a - 2 * b; d1 = -2 * b; d2 = 2 * (a - b);
            while (y > y1)
            {
                if (d <= 0) { x++; d += d2; }
                else d += d1;
                y--;
                addPoint(x, y, 0);
            }
        }
    }
    
  • 相关阅读:
    Linux常用命令及示例(全)
    linux下安装配置svn服务器
    Kafka、Redis和其它消息组件比较
    ORACLE定时备份方案
    mysql库表优化实例
    携程apollp快速部署DVE集群
    windows 安装Zookeeper 配置集群
    Ubuntu 18.04 LTS 修改Host,使用Host访问
    PowerShell因为在此系统中禁止执行脚本......
    常用第三方工具的Docker命令
  • 原文地址:https://www.cnblogs.com/tetew/p/12542187.html
Copyright © 2011-2022 走看看