📄 cvgshape.cpp
字号:
/* GHelm - Nautical Navigation Software * Copyright (C) 2004 Jon Michaelchuck * * This application is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */#include <iostream>#include <GL/gl.h>#include <GL/glu.h>#include "cvgshape.h"#include "cvgutil.h"#include "cvg.h"/** * Constructor */CVGLine::CVGLine(){ p0 = new double[2]; p1 = new double[2];}/** * Destructor */CVGLine::~CVGLine(){ delete [] p0; delete [] p1;}/** * Constructor */CVGRect::CVGRect(){ p0 = new double[2]; p1 = new double[2]; p2 = new double[2]; p3 = new double[2];}/** * Destructor */CVGRect::~CVGRect(){ delete [] p0; delete [] p1; delete [] p2; delete [] p3;}/** * Constructor */CVGFillable::CVGFillable() : filled(false){ fill_rgb[0] = fill_rgb[1] = fill_rgb[2] = 0;}/** * Load rect attributes * @param doc xml doc * @param cur xml cursor * @return 0 on success, -1 on failure */int CVGRect::Load(xmlDocPtr doc, xmlNodePtr cur){ xmlChar *prop; if (CVGFillable::Load(doc, cur) < 0) { std::cerr << "CVGRect::Load(): Error loading fillable" << std::endl; return -1; } if (stroke_group.Load(doc, cur) < 0) { std::cerr << "CVGRect::Load(): Error loading stroke group" << std::endl; return -1; } stroke_group.loop = true; double x, y, width, height; prop = xmlGetProp(cur, (const xmlChar *)"x"); if (!prop) { std::cout << "CVGRect::Load: no x" << std::endl; return -1; } x = atof((const char *)prop); prop = xmlGetProp(cur, (const xmlChar *)"y"); if (!prop) { std::cout << "CVGRect::Load: no y" << std::endl; return -1; } y = atof((const char *)prop); prop = xmlGetProp(cur, (const xmlChar *)"width"); if (!prop) { std::cout << "CVGRect::Load: no width" << std::endl; return -1; } width = atof((const char *)prop); prop = xmlGetProp(cur, (const xmlChar *)"height"); if (!prop) { std::cout << "CVGRect::Load: no height" << std::endl; return -1; } height = atof((const char *)prop); p0[0] = x; p0[1] = y; p1[0] = x; p1[1] = y + height; p2[0] = x + width; p2[1] = y + height; p3[0] = x + width; p3[1] = y; stroke_group.verts.push_back(p0); stroke_group.verts.push_back(p1); stroke_group.verts.push_back(p2); stroke_group.verts.push_back(p3); return 0;}/** * Render the rect */void CVGRect::Render(){ if (filled) { glColor3fv(fill_rgb); glBegin(GL_QUADS); glVertex2dv(p0); glVertex2dv(p1); glVertex2dv(p2); glVertex2dv(p3); glEnd(); } stroke_group.Render();}/** * Load circle object * @param doc xml doc * @param cur xml cursor * @return 0 on success, -1 on failure */int CVGCircle::Load(xmlDocPtr doc, xmlNodePtr cur){ xmlChar *prop; if (CVGFillable::Load(doc, cur) < 0) { std::cerr << "CVGCircle::Load(): Error loading fillable" << std::endl; return -1; } if (stroke_group.Load(doc, cur) < 0) { std::cerr << "CVGCircle::Load(): Error loading stroke group" << std::endl; return -1; } prop = xmlGetProp(cur, (const xmlChar *)"cx"); if (!prop) { std::cout << "CVGCircle::Load() no cx" << std::endl; return -1; } x = atof((const char *)prop); prop = xmlGetProp(cur, (const xmlChar *)"cy"); if (!prop) { std::cout << "CVGCircle::Load no cy" << std::endl; return -1; } y = atof((const char *)prop); prop = xmlGetProp(cur, (const xmlChar *)"r"); if (!prop) { std::cout << "CVGCircle::Load: no r" << std::endl; return -1; } radius = atof((const char *)prop); return 0;}/** * Render circle */void CVGCircle::Render(){ glPushMatrix(); glTranslatef(x, y, 0); if (filled) { glColor3fv(fill_rgb); glBegin(GL_POLYGON); for (int i=0; i < 360; i += 10) { float radians = i * DEG2RAD; glVertex2f(cos(radians) * radius, sin(radians) * radius); } glEnd(); } // FIXME draw outline! glPopMatrix();}/** * Load ellipse object * @param doc xml doc * @param cur xml cursor * @return 0 on success, -1 on failure */int CVGEllipse::Load(xmlDocPtr doc, xmlNodePtr cur){ xmlChar *prop; if (CVGFillable::Load(doc, cur) < 0) { std::cerr << "CVGCircle::Load(): Error loading fillable" << std::endl; return -1; } if (stroke_group.Load(doc, cur) < 0) { std::cerr << "CVGCircle::Load(): Error loading stroke group" << std::endl; return -1; } prop = xmlGetProp(cur, (const xmlChar *)"cx"); if (!prop) { std::cout << "CVGCircle::Load() no cx" << std::endl; return -1; } x = atof((const char *)prop); prop = xmlGetProp(cur, (const xmlChar *)"cy"); if (!prop) { std::cout << "CVGCircle::Load no cy" << std::endl; return -1; } y = atof((const char *)prop); prop = xmlGetProp(cur, (const xmlChar *)"rx"); if (!prop) { std::cout << "CVGCircle::Load: no rx" << std::endl; return -1; } xradius = atof((const char *)prop); prop = xmlGetProp(cur, (const xmlChar *)"ry"); if (!prop) { std::cout << "CVGCircle::Load: no ry" << std::endl; return -1; } yradius = atof((const char *)prop); return 0;}/** * Render ellipse */void CVGEllipse::Render(){ glPushMatrix(); glTranslatef(x, y, 0); if (filled) { glColor3fv(fill_rgb); glBegin(GL_POLYGON); for (int i=0; i < 360; i += 10) { float radians = i * DEG2RAD; glVertex2f(cos(radians) * xradius, sin(radians) * yradius); } glEnd(); } // FIXME draw outline! glPopMatrix();}/** * Load polygon object * @param doc xml doc * @param cur xml cursor * @return 0 on success, -1 on failure */int CVGPolygon::Load(xmlDocPtr doc, xmlNodePtr cur){ xmlChar *prop; if (CVGFillable::Load(doc, cur) < 0) { std::cerr << "CVGPolygon::Load(): Error loading fillable" << std::endl; return -1; } if (stroke_group.Load(doc, cur) < 0) { std::cerr << "CVGPolygon::Load(): Error loading stroke group" << std::endl; return -1; } stroke_group.loop = true; prop = xmlGetProp(cur, (const xmlChar *)"points"); if (!prop) { std::cout << "CVGPolygon::Load: no points" << std::endl; return -1; } std::string points = (const char *)prop; std::string::size_type foo; std::string prefix; std::string delim = " "; std::string x, y; points = _remove_whitespace(points); while (!points.empty()) { foo = points.find_first_of(delim); prefix = points.substr(0, foo); prefix = _remove_whitespace(prefix); if (foo <= points.size()) { points = points.substr(foo); } points = _remove_whitespace(points); x = _get_prefix(prefix, ","); y = _get_suffix(prefix, ","); double *tmp = new double[2]; tmp[0] = atof(x.c_str()); tmp[1] = atof(y.c_str()); verts.push_back(tmp); stroke_group.verts.push_back(tmp); if (foo > points.size()) { break; } } return 0;}/** * Render polygon */void CVGPolygon::Render(){ if (filled) { glColor3fv(fill_rgb); glBegin(GL_POLYGON); std::vector<double *>::iterator vert_it; for (vert_it = verts.begin(); vert_it != verts.end(); ++vert_it) glVertex2d((*vert_it)[0], (*vert_it)[1]); glEnd(); } stroke_group.Render();}/** * Load polyline object * @param doc xml doc * @param cur xml cursor * @return 0 on success, -1 on failure */int CVGPolyline::Load(xmlDocPtr doc, xmlNodePtr cur){ xmlChar *prop; if (CVGFillable::Load(doc, cur) < 0) { std::cerr << "CVGPolyline::Load(): Error loading fillable" << std::endl; return -1; } if (stroke_group.Load(doc, cur) < 0) { std::cerr << "CVGPolyline::Load(): Error loading stroke group" << std::endl; return -1; } stroke_group.loop = false; prop = xmlGetProp(cur, (const xmlChar *)"points"); if (!prop) { std::cout << "CVGPolyline::Load: no points" << std::endl; return -1; } std::string points = (const char *)prop; std::string::size_type foo; std::string prefix; std::string delim = " "; std::string x, y; points = _remove_whitespace(points); while (!points.empty()) { foo = points.find_first_of(delim); prefix = points.substr(0, foo); prefix = _remove_whitespace(prefix); if (foo <= points.size()) { points = points.substr(foo); } points = _remove_whitespace(points); x = _get_prefix(prefix, ","); y = _get_suffix(prefix, ","); double *tmp = new double[2]; tmp[0] = atof(x.c_str()); tmp[1] = atof(y.c_str()); verts.push_back(tmp); stroke_group.verts.push_back(tmp); if (foo > points.size()) { break; } } return 0;}/** * Render polyline */void CVGPolyline::Render(){ if (filled) { glColor3fv(fill_rgb); glBegin(GL_LINE_STRIP); std::vector<double *>::iterator vert_it; for (vert_it = verts.begin(); vert_it != verts.end(); ++vert_it) glVertex2d((*vert_it)[0], (*vert_it)[1]); glEnd(); } stroke_group.Render();}/** * Load line object * @param doc xml doc * @param cur xml cursor * @return 0 on success, -1 on failure */int CVGLine::Load(xmlDocPtr doc, xmlNodePtr cur){ xmlChar *prop; if (stroke_group.Load(doc, cur) < 0) { std::cerr << "CVGPolygon::Load(): Error loading stroke group" << std::endl; return -1; } stroke_group.loop = false; prop = xmlGetProp(cur, (const xmlChar *)"x1"); if (!prop) { std::cout << "CVGLine::Load: no x1" << std::endl; return -1; } p0[0] = atof((const char *)prop); prop = xmlGetProp(cur, (const xmlChar *)"y1"); if (!prop) { std::cout << "CVGLine::Load: no y1" << std::endl; return -1; } p0[1] = atof((const char *)prop); prop = xmlGetProp(cur, (const xmlChar *)"x2"); if (!prop) { std::cout << "CVGLine::Load: no x2" << std::endl; return -1; } p1[0] = atof((const char *)prop); prop = xmlGetProp(cur, (const xmlChar *)"y2"); if (!prop) { std::cout << "CVGLine::Load: no y2" << std::endl; return -1; } p1[1] = atof((const char *)prop); stroke_group.verts.push_back(p0); stroke_group.verts.push_back(p1); return 0;}/** * Render line */void CVGLine::Render(){ stroke_group.Render();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -