CQIllustratorShapeNearestPoint2D CQIllustratorShape:: nearestPoint(const CPoint2D &p, ControlType type) const { CQIllustratorShapeNearestPoint2D nearest; ControlPointList points; getControlPoints(points, type); uint num_points = points.size(); for (uint i = 0; i < num_points; ++i) { double dist = points[i]->distance(this, p); nearest.updatePoint(points[i], dist); } return nearest; }
void sineTest( void ) { title = "Sine Test"; ControlPoint cp; cp = ControlPoint( Vector3(0.0, 0.0, 0.0), CONTROL_POINT_END ); cplist.push_back(cp); cp = ControlPoint( Vector3(0.0, 0.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(PI/2.0, 1.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(PI*3.0/2.0, -1.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(2*PI, 0.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(2*PI, 0.0, 0.0), CONTROL_POINT_END ); cplist.push_back(cp); camera.position = Vector3( PI, 0.0, 6.0 ); camera.viewpoint = Vector3( PI, 0.0, 5.0 ); }
void lineTest( void ) { title = "Line Test"; ControlPoint cp; cp = ControlPoint( Vector3(-5.0, 0.0, 0.0), CONTROL_POINT_END ); cplist.push_back(cp); cp = ControlPoint( Vector3(-5.0, 0.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(0.0, 0.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(5.0, 0.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(5.0, 0.0, 0.0), CONTROL_POINT_END ); cplist.push_back(cp); camera.position = Vector3( 0.0, 0.0, 10.0 ); camera.viewpoint = Vector3( 0.0, 0.0, 9.0 ); }
void immelmannTest( void ) { title = "Immelmann Test"; ControlPoint cp; cp = ControlPoint( Vector3(-1.0, -1.0, 0.0), CONTROL_POINT_END ); cplist.push_back(cp); cp = ControlPoint( Vector3(-1.0, -1.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(0.0, -1.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(cos(PI/4), -sin(PI/4), 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(1.0, 0.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(cos(PI/4), sin(PI/4), 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(0.0, 1.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(-1.0, 1.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(-1.0, 1.0, 0.0), CONTROL_POINT_END ); cplist.push_back(cp); camera.position = Vector3( 0.0, 0.0, 3.0 ); camera.viewpoint = Vector3( 0.0, 0.0, 2.0 ); }
void compressedsineandsineTest( void ) { title = "Compressed Sine And Sine Test"; ControlPoint cp; cp = ControlPoint( Vector3(0.0, 0.0, 0.0), CONTROL_POINT_END ); cplist.push_back(cp); // compressed amplitude sine cp = ControlPoint( Vector3(0.0, 0.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(PI/4.0, 1.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(PI*3/4.0, -1.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); // remarked for better continuity over both catmullrom and bspline //cp = ControlPoint( Vector3(PI, 0.0, 0.0), CONTROL_POINT_MIDDLE ); //cplist.push_back(cp); // normal amplitude sine cp = ControlPoint( Vector3(PI+PI/2.0, 1.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(PI+PI*3.0/2.0, -1.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(PI+2*PI, 0.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(PI+2*PI, 0.0, 0.0), CONTROL_POINT_END ); cplist.push_back(cp); camera.position = Vector3( (PI+PI/2.0), 0.0, 8.0 ); camera.viewpoint = Vector3( (PI+PI/2.0), 0.0, 7.0 ); }
//------------------------------------------------------------------------------ int main(int argc, char** argv) { //lineTest(); //circleTest(); //sineTest(); //immelmannTest(); //dblimmelmannTest(); compressedsineandsineTest(); glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB |GLUT_DEPTH); glutInitWindowSize (600, 600); glutInitWindowPosition (100, 100); glutCreateWindow ( title.c_str() ); catmullrom_s = CubicSpline::linearly_interpolate_arclength( CUBIC_SPLINE_CATMULLROM, cplist ); catmullrom_M = CubicSpline::basisCatmullRom(); catmullrom_arclength_map = CubicSpline::map_spline( CUBIC_SPLINE_CATMULLROM, cplist ); std::cout << "catmullrom arclength s:" << catmullrom_s << std::endl; bspline_s = CubicSpline::linearly_interpolate_arclength( CUBIC_SPLINE_B, cplist ); bspline_M = CubicSpline::basisUniformNonrationalBSpline(); bspline_arclength_map = CubicSpline::map_spline( CUBIC_SPLINE_B, cplist ); std::cout << "bspline arclength s:" << bspline_s << std::endl; ControlPointList::iterator it = cplist.begin()+1; actor_position = Vector3( it->position ); actor_transform.identity(); camera.project(); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutIdleFunc(idle); glutMainLoop(); return 0; }
void CQIllustratorShape:: getControlPoints(ControlPointList &points, ControlType type) const { if (type == ControlType::GEOMETRY) { } else if (type == ControlType::LGRADIENT) { const CQIllustratorShapeFill &fill = getFill(); const CGenGradient *g = fill.getGradient(); const CLinearGradient *lg = dynamic_cast<const CLinearGradient *>(g); if (! lg) return; //CBBox2D bbox = getFlatBBox(); //double x1 = lg->getX1()*(bbox.getXMax() - bbox.getXMin()) + bbox.getXMin(); //double y1 = lg->getY1()*(bbox.getYMax() - bbox.getYMin()) + bbox.getYMin(); //double x2 = lg->getX2()*(bbox.getXMax() - bbox.getXMin()) + bbox.getXMin(); //double y2 = lg->getY2()*(bbox.getYMax() - bbox.getYMin()) + bbox.getYMin(); CPoint2D p1(lg->getX1(), lg->getY1()); CPoint2D p2(lg->getX2(), lg->getY2()); CQIllustratorShapeLGradientControlPoint *start = new CQIllustratorShapeLGradientControlPoint( CQIllustratorShapeLGradientControlPoint::Position::START, p1); CQIllustratorShapeLGradientControlPoint *end = new CQIllustratorShapeLGradientControlPoint( CQIllustratorShapeLGradientControlPoint::Position::END , p2); points.push_back(start); points.push_back(end); } else if (type == ControlType::RGRADIENT) { const CQIllustratorShapeFill &fill = getFill(); const CGenGradient *g = fill.getGradient(); const CRadialGradient *rg = dynamic_cast<const CRadialGradient *>(g); if (! rg) return; //CBBox2D bbox = getFlatBBox(); //double x1 = rg->getX1()*(bbox.getXMax() - bbox.getXMin()) + bbox.getXMin(); //double y1 = rg->getY1()*(bbox.getYMax() - bbox.getYMin()) + bbox.getYMin(); //double x2 = rg->getX2()*(bbox.getXMax() - bbox.getXMin()) + bbox.getXMin(); //double y2 = rg->getY2()*(bbox.getYMax() - bbox.getYMin()) + bbox.getYMin(); CPoint2D c(rg->getCenterX(), rg->getCenterY()); CPoint2D f(rg->getFocusX (), rg->getFocusY ()); double r1 = rg->getRadius()/sqrt(2); CPoint2D rp(c.x + r1, c.y + r1); CQIllustratorShapeRGradientControlPoint *center = new CQIllustratorShapeRGradientControlPoint( CQIllustratorShapeRGradientControlPoint::Position::CENTER, c); CQIllustratorShapeRGradientControlPoint *focus = new CQIllustratorShapeRGradientControlPoint( CQIllustratorShapeRGradientControlPoint::Position::FOCUS , f); CQIllustratorShapeRGradientControlPoint *radius = new CQIllustratorShapeRGradientControlPoint( CQIllustratorShapeRGradientControlPoint::Position::RADIUS, rp); points.push_back(center); points.push_back(focus); points.push_back(radius); } }
//------------------------------------------------------------------------------ /// Simple Euler integration void integrate_actor( void ) { int qi = 0; bool failed = true; SdS sds, sdsi; unsigned int n = cplist.size(); for( unsigned int i = 2; i < n-1; i++ ) { sdsi = catmullrom_arclength_map.at( i ); if( actor_ds < sdsi.first ) { sds = catmullrom_arclength_map.at( i-1 ); qi = i; failed = false; break; } } if( failed ) { std::cout << "failed to find the next control point -> off the spline\n"; return; // failed to find the next control point -> off the spline } Eigen::MatrixXd C = CubicSpline::blend( catmullrom_M, cplist, qi ); double qi_ds = sdsi.second; double qip_s = sds.first; // where the actor will be in terms of arclength after the step is taken double s1 = actor_dsdt * sim_dt + (actor_ds - qip_s); double u = (double)s1 / (double)qi_ds; Vector3 vi1 = CubicSpline::position( C, u ); // update the actor position actor_position = vi1; // advance the actor for next tick actor_ds = s1 + qip_s; // advance the sim time sim_t += sim_dt; Vector3 v_w = CubicSpline::tangent( C, u ); v_w.normalize(); double wdotup = Vector3::dot( v_w, actor_up ); double wdotforward = Vector3::dot( v_w, actor_forward ); double theta = acos(wdotforward); if( wdotup < 0.0 ) { theta = -theta; // pitch down } Matrix3 R = Matrix3::rotZ( theta ); actor_up = R * actor_up; actor_up.normalize(); actor_forward = v_w; actor_left = Vector3::cross( actor_forward, actor_up ); actor_left.normalize(); actor_transform = Matrix4( actor_forward(0), actor_up(0), actor_left(0), actor_position.x(), actor_forward(1), actor_up(1), actor_left(1), actor_position.y(), actor_forward(2), actor_up(2), actor_left(2), actor_position.z(), 0.0, 0.0, 0.0, 1.0 ); }
//------------------------------------------------------------------------------ // Spline Functions //------------------------------------------------------------------------------ void draw_spline( const ECubicSplineBasis& basis ) { glPushMatrix(); Eigen::MatrixXd M; GLfloat material_Ka[4] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat material_Kd[4] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat material_Ks[4] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat material_Ke[4] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat material_Se = 10; switch( basis ) { case CUBIC_SPLINE_CATMULLROM: default: material_Ka[0] = catmullrom_Ka(0); material_Ka[1] = catmullrom_Ka(1); material_Ka[2] = catmullrom_Ka(2); material_Kd[0] = catmullrom_Kd(0); material_Kd[1] = catmullrom_Kd(1); material_Kd[2] = catmullrom_Kd(2); material_Ks[0] = catmullrom_Ks(0); material_Ks[1] = catmullrom_Ks(1); material_Ks[2] = catmullrom_Ks(2); material_Ke[0] = catmullrom_Ke(0); material_Ke[1] = catmullrom_Ke(1); material_Ke[2] = catmullrom_Ke(2); M = catmullrom_M; break; case CUBIC_SPLINE_B: material_Ka[0] = bspline_Ka(0); material_Ka[1] = bspline_Ka(1); material_Ka[2] = bspline_Ka(2); material_Kd[0] = bspline_Kd(0); material_Kd[1] = bspline_Kd(1); material_Kd[2] = bspline_Kd(2); material_Ks[0] = bspline_Ks(0); material_Ks[1] = bspline_Ks(1); material_Ks[2] = bspline_Ks(2); material_Ke[0] = bspline_Ke(0); material_Ke[1] = bspline_Ke(1); material_Ke[2] = bspline_Ke(2); M = bspline_M; break; } glMaterialfv(GL_FRONT, GL_AMBIENT, material_Ka); glMaterialfv(GL_FRONT, GL_DIFFUSE, material_Kd); glMaterialfv(GL_FRONT, GL_SPECULAR, material_Ks); glMaterialfv(GL_FRONT, GL_EMISSION, material_Ke); glMaterialf(GL_FRONT, GL_SHININESS, material_Se); Vector3 vi, vi1; unsigned int n = cplist.size(); glLineWidth( line_width ); glBegin(GL_LINES); for( unsigned int i = 2; i < n-1; i++ ) { Eigen::MatrixXd C = CubicSpline::blend( M, cplist, i ); std::vector<Vector3> points; for( double u = 0.0; u < 1.0; u += 0.1 ) { points.push_back( CubicSpline::position( C, u ) ); } points.push_back( CubicSpline::position( C, 1.0 ) ); for( std::vector<Vector3>::iterator it = points.begin(); it != points.end(); it++ ) { if( it == points.begin() ) { vi = *it; } else { vi1 = *it; glVertex3d( vi.x(), vi.y(), vi.z() ); glVertex3d( vi1.x(), vi1.y(), vi1.z() ); vi = *it; } } } glEnd(); glPopMatrix(); }
void dblimmelmannTest( void ) { title = "Double Immelmann Test"; ControlPoint cp; // first immelmann cp = ControlPoint( Vector3(-2.0, -1.0, 0.0), CONTROL_POINT_END ); cplist.push_back(cp); cp = ControlPoint( Vector3(-2.0, -1.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(0.0, -1.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(cos(PI/4), -sin(PI/4), 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(1.0, 0.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(cos(PI/4), sin(PI/4), 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(0.0, 1.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); // second immelmann cp = ControlPoint( Vector3(-cos(PI/4), 2.0-sin(PI/4), 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(-1.0, 2.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(-cos(PI/4), 2.0+sin(PI/4), 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(0.0, 3.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(2.0, 3.0, 0.0), CONTROL_POINT_MIDDLE ); cplist.push_back(cp); cp = ControlPoint( Vector3(2.0, 3.0, 0.0), CONTROL_POINT_END ); cplist.push_back(cp); camera.position = Vector3( 0.0, 1.0, 4.0 ); camera.viewpoint = Vector3( 0.0, 1.0, 3.0 ); }