⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cvgstrokegroup.cpp

📁 开源的电子海图程序
💻 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 "cvgstrokegroup.h"#include "cvgutil.h"#include "cvg.h"#include <iostream>#include <GL/gl.h>#include <GL/glu.h>CVGStrokeGroup::CVGStrokeGroup() :    width(1), loop(false), linecap(LINECAP_BUTT), linejoint(LINEJOINT_MITER){    rgb[0] = rgb[1] = rgb[2] = 0;}CVGStrokeGroup::~CVGStrokeGroup(){    // NOTE we don't delete the verts pointers; these are taken    // care of in the shape classes.}/** * Load stroke group  * @param doc xml doc * @param cur xml cursor * @return 0 on success, -1 on failure */int CVGStrokeGroup::Load(xmlDocPtr doc, xmlNodePtr cur){    xmlChar *prop;    prop = xmlGetProp(cur, (const xmlChar *)"stroke");    if (prop) {        std::string stroke = (const char *)prop;        if (stroke.size() != 7) {            std::cout << "CVGStrokeGroup::Load: bad parameter" << std::endl;            return -1;        }        rgb[0] = _hex_to_dec(stroke.substr(1,2))/255.0;        rgb[1] = _hex_to_dec(stroke.substr(3,2))/255.0;        rgb[2] = _hex_to_dec(stroke.substr(5,2))/255.0;    }    prop = xmlGetProp(cur, (const xmlChar *)"stroke-width");    if (prop)        width = atof((const char *)prop);    prop = xmlGetProp(cur, (const xmlChar *)"stroke-linecap");    if (prop) {        if (!xmlStrcmp(prop, (const xmlChar *) "butt"))            linecap = LINECAP_BUTT;        else if (!xmlStrcmp(prop, (const xmlChar *) "round"))            linecap = LINECAP_ROUND;        else if (!xmlStrcmp(prop, (const xmlChar *) "square"))            linecap = LINECAP_SQUARE;        else            std::cerr << "CVGStrokeGroup::Load: Unknown linecap "                      << prop << std::endl;    }    prop = xmlGetProp(cur, (const xmlChar *)"stroke-linejoint");    if (prop) {        if (!xmlStrcmp(prop, (const xmlChar *) "miter"))            linejoint = LINEJOINT_MITER;        else if (!xmlStrcmp(prop, (const xmlChar *) "round"))            linejoint = LINEJOINT_ROUND;        else if (!xmlStrcmp(prop, (const xmlChar *) "bevel"))            linejoint = LINEJOINT_BEVEL;        else            std::cerr << "CVGStrokeGroup::Load: Unknown linejoint "                      << prop << std::endl;    }    return 0;}/** Draw stroke group */void CVGStrokeGroup::Render(){    glColor3fv(rgb);    double dx, dy;    double butt_dx, butt_dy;    double theta;    double lastv0[2];    double lastv1[2];    double firstv0[2];    double firstv1[2];    double vert0[2];    double vert1[2];    std::vector<double *>::iterator it;    for (it = verts.begin(); (it+1) != verts.end(); ++it) {        vert0[0] = (*it)[0];        vert0[1] = (*it)[1];        vert1[0] = (*(it+1))[0];        vert1[1] = (*(it+1))[1];                dx = vert1[0] - vert0[0];        dy = vert1[1] - vert0[1];        if (dx == 0) {            butt_dx = width/2;            butt_dy = 0;        } else {            theta = atan(dy/dx);            butt_dx = sin(theta) * width/2;            butt_dy = cos(theta) * width/2;        }        glBegin(GL_QUADS);            glVertex2d(vert0[0] - butt_dx, vert0[1] + butt_dy);            glVertex2d(vert0[0] + butt_dx, vert0[1] - butt_dy);            glVertex2d(vert1[0] + butt_dx, vert1[1] - butt_dy);            glVertex2d(vert1[0] - butt_dx, vert1[1] + butt_dy);        glEnd();        if (it != verts.begin()) {            switch (linejoint)            {                case LINEJOINT_MITER:                    break;                case LINEJOINT_ROUND:                  {                    float radius = width/2;                    glPushMatrix();                        glTranslatef(vert0[0], vert0[1], 0);                        glBegin(GL_POLYGON);                            for (int i=0; i <= 360; i += 10) {                              float radians = -i * DEG2RAD;                              glVertex2f(cos(radians) * radius,                                         sin(radians) * radius);                            }                        glEnd();                    glPopMatrix();                  }                  break;                case LINEJOINT_BEVEL:                       glBegin(GL_QUADS);                        glVertex2dv(lastv0);                        glVertex2d(vert0[0] + butt_dx, vert0[1] - butt_dy);                        glVertex2dv(lastv1);                        glVertex2d(vert0[0] - butt_dx, vert0[1] + butt_dy);                    glEnd();                    break;                default:                    break;            }        } else {            firstv0[0] = vert0[0] - butt_dx;            firstv0[1] = vert0[1] + butt_dy;            firstv1[0] = vert0[0] + butt_dx;            firstv1[1] = vert0[1] - butt_dy;        }        lastv0[0] = vert1[0] + butt_dx;        lastv0[1] = vert1[1] - butt_dy;        lastv1[0] = vert1[0] - butt_dx;        lastv1[1] = vert1[1] + butt_dy;    }    vert0[0] = (*it)[0];    vert0[1] = (*it)[1];    vert1[0] = (*(verts.begin()))[0];    vert1[1] = (*(verts.begin()))[1];    if (loop) {        dx = vert0[0] - vert1[0];        dy = vert0[1] - vert1[1];        if (dx == 0) {            butt_dx = width/2;            butt_dy = 0;        } else {            theta = atan(dy/dx);            butt_dx = sin(theta) * width/2;            butt_dy = cos(theta) * width/2;        }        glBegin(GL_QUADS);            glVertex2d(vert0[0] - butt_dx, vert0[1] + butt_dy);            glVertex2d(vert0[0] + butt_dx, vert0[1] - butt_dy);            glVertex2d(vert1[0] + butt_dx, vert1[1] - butt_dy);            glVertex2d(vert1[0] - butt_dx, vert1[1] + butt_dy);        glEnd();        switch (linejoint)        {            case LINEJOINT_MITER:                break;            case LINEJOINT_ROUND:              {                float radius = width/2;                glPushMatrix();                    glTranslatef(vert0[0], vert0[1], 0);                    glBegin(GL_POLYGON);                        for (int i=0; i <= 360; i += 10) {                          float radians = -i * DEG2RAD;                          glVertex2f(cos(radians) * radius,                                     sin(radians) * radius);                        }                    glEnd();                glPopMatrix();                 glPushMatrix();                    glTranslatef(vert1[0], vert1[1], 0);                    glBegin(GL_POLYGON);                        for (int i=0; i <= 360; i += 10) {                          float radians = -i * DEG2RAD;                          glVertex2f(cos(radians) * radius,                                     sin(radians) * radius);                        }                    glEnd();                glPopMatrix();               }              break;            case LINEJOINT_BEVEL:                glBegin(GL_QUADS);                    glVertex2dv(lastv0);                    glVertex2d(vert0[0] + butt_dx, vert0[1] - butt_dy);                    glVertex2dv(lastv1);                    glVertex2d(vert0[0] - butt_dx, vert0[1] + butt_dy);                    glVertex2dv(firstv0);                    glVertex2d(vert1[0] + butt_dx, vert1[1] - butt_dy);                    glVertex2dv(firstv1);                    glVertex2d(vert1[0] - butt_dx, vert1[1] + butt_dy);                glEnd();                break;            default:                break;        }    } else { // draw the linecaps FIXME eventually we just want to draw one,             // and only draw the other if this is just a single line seg.        switch (linecap)         {            case LINECAP_BUTT:                break;            case LINECAP_ROUND:              {                float radius = width/2;                glPushMatrix();                    glTranslatef(vert0[0], vert0[1], 0);                    glBegin(GL_POLYGON);                        for (int i=0; i <= 360; i += 10) {                          float radians = -i * DEG2RAD;                          glVertex2f(cos(radians) * radius,                                     sin(radians) * radius);                        }                    glEnd();                glPopMatrix();                glPushMatrix();                    glTranslatef(vert1[0], vert1[1], 0);                    glBegin(GL_POLYGON);                        for (int i=0; i <= 360; i += 10) {                          float radians = i * DEG2RAD;                          glVertex2f(cos(radians) * radius,                                     sin(radians) * radius);                        }                    glEnd();                glPopMatrix();              }              break;            case LINECAP_SQUARE:                break;            default:                break;        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -