gpt4 book ai didi

c++ - OpenGL - 帮助限制曲线永远不会越界

转载 作者:太空宇宙 更新时间:2023-11-04 13:51:57 25 4
gpt4 key购买 nike

我有以下使用贝塞尔曲线绘制圆弧的程序:

#include <GL/gl.h>
#include <GL/glu.h>
#include <stdlib.h>
#include <GL/openglut.h>
#include <math.h>
#include <stdio.h>
#include <iostream>
#include <time.h>
#include <ctime>
#include <cstdlib>
#include <fstream>
#include <sstream>


std::ofstream nul("/dev/null");
std::ostream * err=&std::cerr;

class Point {
public:
int _id;
GLfloat _x;
GLfloat _y;
GLfloat _z;

Point(int id, GLfloat x, GLfloat y, GLfloat z) :
_id(id),
_x(x),
_y(y),
_z(z) {
}

void PrintPoint() {
printf("Point %d = <%f, %f, %f>\n", _id, _x, _y, _z);
}
};

Point getControl(Point a, Point b){

if(a._x < b._x && a._y < b._y){
Point ctrl(10, ((a._x+b._x)/2)+(0.25*(b._x-a._x)), ((a._y+b._y)/2)-(0.25*(b._x-a._x)), 0.0);
return ctrl;
} else if(a._x < b._x && a._y > b._y){
Point ctrl(10, ((a._x+b._x)/2)+(0.25*(b._x-a._x)), ((a._y+b._y)/2)-(0.25*(b._x-a._x)), 0.0);
return ctrl;
} else if(b._x < a._x && b._y < a._y){
Point ctrl(10, ((a._x+b._x)/2)+(0.25*(b._x-a._x)), ((a._y+b._y)/2)-(0.25*(b._x-a._x)), 0.0);
return ctrl;
} else if(b._x < a._x && b._y > a._y){
Point ctrl(10, ((a._x+b._x)/2)+(0.25*(b._x-a._x)), ((a._y+b._y)/2)-(0.25*(b._x-a._x)), 0.0);
return ctrl;
} else if(a._x == b._x && a._y != b._y){
Point ctrl(10, ((a._x+b._x)/2) + (0.25*a._x), (a._y+b._y)/2, 0.0);
return ctrl;
} else if(a._x != b._x && a._y == b._y){
Point ctrl(10, ((a._x+b._x)/2), ((a._y+b._y)/2) + (0.25*a._y), 0.0);
return ctrl;
}
return a;
}

GLfloat bezierP(float t, GLfloat P0, GLfloat P1, GLfloat P2, GLfloat P3) {
GLfloat point = (pow((1-t), 3.0) * P0) +
(3 * pow((1-t),2) * t * P1) +
(3 * (1-t) * t * t * P2) +
(pow(t, 3) * P3);
return point;
}

void drawBezierArc(Point start, Point end){

Point ctrl = getControl(start, end);
start.PrintPoint();
end.PrintPoint();
ctrl.PrintPoint();

int i;

glColor3f(1.0, 1.0, 0.0);
glBegin(GL_LINE_STRIP);
int t = 60;
for (i = 0; i <= t; i++) {
float pos = (float) i / (float) t;
GLfloat x = bezierP(pos, start._x, ctrl._x, ctrl._x, end._x);
GLfloat y = bezierP(pos, start._y, ctrl._y, ctrl._y, end._y);
GLfloat z = bezierP(pos, start._z, ctrl._z, ctrl._z, end._z);

glVertex3f(x, y, z);
}
glEnd();

glFlush();
}

void display(void) {

Point start1(0, 6, -2, 0);
Point end1(0, 6, 4, 0);

Point start2(0, 0, 2, 0);
Point end2(0, 4, 3, 0);

Point start3(0, -2, 0, 0);
Point end3(0, 1, 0, 0);

Point start4(0, -4, 3, 0);
Point end4(0, -4, -2, 0);

drawBezierArc(start1, end1);
drawBezierArc(start2, end2);
drawBezierArc(start3, end3);
drawBezierArc(start4, end4);

glFlush();
}

void reshape(int w, int h) {
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

if (w <= h) {
glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w, 5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);
} else {
glOrtho(-5.0*(GLfloat)w/(GLfloat)h, 5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);
}

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

int main(int argc, char** argv){
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (640, 480);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);

glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glShadeModel(GL_FLAT);

glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}

Problem

这里的曲线是用贝塞尔曲线制作的,所以每条曲线都是一系列的直线,使它看起来像一条弧线/曲线。正如您从最右侧的弧线看到的那样,它超出了窗口范围。当发生这种情况时,我想限制它并将超出的线保留在窗口内(或者至少沿着窗口的边缘)。

我解决这个问题的方法是减去超出点与 window 边缘的距离,但这似乎不起作用。事情是这样的:

double dist = exceedingPoint - boundaryValue;
exceedingPoint = exceedingPoint - dist;

谢谢!

最佳答案

我不确定这是否真的属于 OpenGL 问题 - 但更多的是解决问题。

取决于您想要什么(以及查看您上面的评论)-

1) 您可以评估贝塞尔曲线的大小(找出矩形的大小,如果它包含该曲线),然后查看它是否会超过窗口大小。调整曲线大小或移动曲线以适应它。

2) 在计算点时对其进行评估。如果它们似乎在窗口之外,则将点的坐标设置为窗口的边缘。

3) 学习 GLSL 并弄清楚顶点着色器如何能够完成 #2。

基本上,您可以做很多事情。再试一次!

关于c++ - OpenGL - 帮助限制曲线永远不会越界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23159304/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com