1

ベジエ曲線を使用して円弧を描く次のプログラムがあります。

#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;
}

問題

ここでの曲線はベジエ曲線で作成されているため、各曲線は円弧/曲線のように見える一連の直線です。右端の円弧でわかるように、ウィンドウの境界を超えています。このようなことが起こった場合、私はそれを制限して、ウィンドウ内の超過行を保持したいと考えています (または、少なくともウィンドウの端に沿って移動します)。

この問題に対する私の取り組みは、ウィンドウの端から超過ポイントまでの距離を差し引くことでしたが、これはうまくいかないようでした。それは次のようなものでした:

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

ありがとう!

4

1 に答える 1