//Mouse listener void mouse_callback(GLFWwindow* window, int btn, int action, int mods){ if (action == GLFW_RELEASE && btn == GLFW_MOUSE_BUTTON_LEFT){ //Create a snow shape, if none exist if (snow_shapes.empty()) create_new_shape(); //Add vertex to the shape double x, y; glfwGetCursorPos(window, &x, &y); //Convert screen coordinates to world y = (1-y/WIN_SIZE)*WIN_METERS; x = x/WIN_SIZE*WIN_METERS; //Regular point switch (circle_draw_state){ //Regular point case 0: snow_shapes.back()->addPoint(x, y); break; //Circle origin case 1: circle_origin.setData(x, y); circle_draw_state = 2; break; //Circle radius case 2: const int segments = 18; //Cool circle algorithm: http://slabode.exofire.net/circle_draw.shtml float x_dif = circle_origin[0] - x, y_dif = circle_origin[1] - y, radius = sqrt(x_dif*x_dif + y_dif*y_dif), theta = 6.283185307 / (float) segments, tan_fac = tan(theta), cos_fac = cos(theta), x = radius, y = 0; for (int i=0; i<segments; i++){ snow_shapes.back()->addPoint(x+circle_origin[0], y+circle_origin[1]); float flip_x = -y, flip_y = x; x += flip_x*tan_fac; y += flip_y*tan_fac; x *= cos_fac; y *= cos_fac; } circle_draw_state = 0; break; } dirty_buffer = true; } }