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

📄 rs_spline.cpp

📁 qcad2.05可用于windows和linux的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** $Id: rs_spline.cpp 2367 2005-04-04 16:57:36Z andrew $**** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.**** This file is part of the qcadlib Library project.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid qcadlib Professional Edition licenses may use ** this file in accordance with the qcadlib Commercial License** Agreement provided with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.ribbonsoft.com for further details.**** Contact info@ribbonsoft.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "rs_spline.h"#include "rs_debug.h"#include "rs_graphicview.h"#include "rs_painter.h"#include "rs_graphic.h"/** * Constructor. */RS_Spline::RS_Spline(RS_EntityContainer* parent,                     const RS_SplineData& d)        :RS_EntityContainer(parent), data(d) {    calculateBorders();}/** * Destructor. */RS_Spline::~RS_Spline() {}RS_Entity* RS_Spline::clone() {    RS_Spline* l = new RS_Spline(*this);	l->entities.setAutoDelete(entities.autoDelete());    l->initId();    l->detach();    return l;}void RS_Spline::calculateBorders() {    /*minV = RS_Vector::minimum(data.startpoint, data.endpoint);    maxV = RS_Vector::maximum(data.startpoint, data.endpoint);    RS_ValueList<RS_Vector>::iterator it;    for (it = data.controlPoints.begin();     it!=data.controlPoints.end(); ++it) {    minV = RS_Vector::minimum(*it, minV);    maxV = RS_Vector::maximum(*it, maxV);}    */}RS_VectorSolutions RS_Spline::getRefPoints() {    RS_VectorSolutions ret(data.controlPoints.count());    int i=0;    RS_ValueList<RS_Vector>::iterator it;    for (it = data.controlPoints.begin();            it!=data.controlPoints.end(); ++it, ++i) {        ret.set(i, (*it));    }    return ret;}RS_Vector RS_Spline::getNearestRef(const RS_Vector& coord,                                   double* dist) {    //return getRefPoints().getClosest(coord, dist);    return RS_Entity::getNearestRef(coord, dist);}RS_Vector RS_Spline::getNearestSelectedRef(const RS_Vector& coord,        double* dist) {    //return getRefPoints().getClosest(coord, dist);    return RS_Entity::getNearestSelectedRef(coord, dist);}/** * Updates the internal polygon of this spline. Called when the  * spline or it's data, position, .. changes. */void RS_Spline::update() {    RS_DEBUG->print("RS_Spline::update");    clear();    if (isUndone()) {        return;    }    if (data.degree<1 || data.degree>3) {        RS_DEBUG->print("RS_Spline::update: invalid degree: %d", data.degree);        return;    }    if (data.controlPoints.count()<(uint)data.degree+1) {        RS_DEBUG->print("RS_Spline::update: not enough control points");        return;    }    resetBorders();    RS_ValueList<RS_Vector> tControlPoints = data.controlPoints;    if (data.closed) {        for (int i=0; i<data.degree; ++i) {            tControlPoints.append(data.controlPoints[i]);        }    }    int i;    int npts = tControlPoints.count();    // order:    int k = data.degree+1;    // resolution:    int p1 = getGraphicVariableInt("$SPLINESEGS", 8) * npts;    double* b = new double[npts*3+1];    double* h = new double[npts+1];    double* p = new double[p1*3+1];    RS_ValueList<RS_Vector>::iterator it;    i = 1;    for (it = tControlPoints.begin(); it!=tControlPoints.end(); ++it) {        b[i] = (*it).x;        b[i+1] = (*it).y;        b[i+2] = 0.0;        RS_DEBUG->print("RS_Spline::update: b[%d]: %f/%f", i, b[i], b[i+1]);        i+=3;    }    // set all homogeneous weighting factors to 1.0    for (i=1; i <= npts; i++) {        h[i] = 1.0;    }    for (i = 1; i <= 3*p1; i++) {        p[i] = 0.0;    }    if (data.closed) {        rbsplinu(npts,k,p1,b,h,p);    } else {        rbspline(npts,k,p1,b,h,p);    }    RS_Vector prev(false);    for (i = 1; i <= 3*p1; i=i+3) {        if (prev.valid) {            RS_Line* line = new RS_Line(this,                                        RS_LineData(prev, RS_Vector(p[i], p[i+1])));            line->setLayer(NULL);            line->setPen(RS_Pen(RS2::FlagInvalid));            addEntity(line);        }        prev = RS_Vector(p[i], p[i+1]);        minV = RS_Vector::minimum(prev, minV);        maxV = RS_Vector::maximum(prev, maxV);    }    delete[] b;    delete[] h;    delete[] p;}RS_Vector RS_Spline::getNearestEndpoint(const RS_Vector& coord,                                        double* dist) {    double minDist = RS_MAXDOUBLE;    double d;    RS_Vector ret(false);    for (uint i=0; i<data.controlPoints.count(); i++) {        d = data.controlPoints[i].distanceTo(coord);        if (d<minDist) {            minDist = d;            ret = data.controlPoints[i];        }    }    if (dist!=NULL) {        *dist = minDist;    }	return ret;}/*// The default implementation of RS_EntityContainer is inaccurate but//   has to do for now..RS_Vector RS_Spline::getNearestPointOnEntity(const RS_Vector& coord,        bool onEntity, double* dist, RS_Entity** entity) {}*/RS_Vector RS_Spline::getNearestCenter(const RS_Vector& /*coord*/,                                      double* dist) {    if (dist!=NULL) {        *dist = RS_MAXDOUBLE;    }    return RS_Vector(false);}RS_Vector RS_Spline::getNearestMiddle(const RS_Vector& /*coord*/,                                      double* dist) {    if (dist!=NULL) {        *dist = RS_MAXDOUBLE;    }    return RS_Vector(false);}RS_Vector RS_Spline::getNearestDist(double /*distance*/,                                    const RS_Vector& /*coord*/,                                    double* dist) {    if (dist!=NULL) {        *dist = RS_MAXDOUBLE;    }    return RS_Vector(false);}void RS_Spline::move(RS_Vector offset) {    RS_ValueList<RS_Vector>::iterator it;    for (it = data.controlPoints.begin();            it!=data.controlPoints.end(); ++it) {        (*it).move(offset);    }    update();}void RS_Spline::rotate(RS_Vector center, double angle) {    RS_ValueList<RS_Vector>::iterator it;    for (it = data.controlPoints.begin();            it!=data.controlPoints.end(); ++it) {        (*it).rotate(center, angle);    }    update();}void RS_Spline::scale(RS_Vector center, RS_Vector factor) {    RS_ValueList<RS_Vector>::iterator it;    for (it = data.controlPoints.begin();            it!=data.controlPoints.end(); ++it) {        (*it).scale(center, factor);    }    update();}void RS_Spline::mirror(RS_Vector axisPoint1, RS_Vector axisPoint2) {    RS_ValueList<RS_Vector>::iterator it;    for (it = data.controlPoints.begin();            it!=data.controlPoints.end(); ++it) {        (*it).mirror(axisPoint1, axisPoint2);    }    update();}void RS_Spline::moveRef(const RS_Vector& ref, const RS_Vector& offset) {    RS_ValueList<RS_Vector>::iterator it;    for (it = data.controlPoints.begin();            it!=data.controlPoints.end(); ++it) {        if (ref.distanceTo(*it)<1.0e-4) {            (*it).move(offset);        }    }    update();}void RS_Spline::draw(RS_Painter* painter, RS_GraphicView* view,                     double /*patternOffset*/) {    if (painter==NULL || view==NULL) {        return;    }    RS_Entity* e = firstEntity(RS2::ResolveNone);    double offset = 0.0;    if (e!=NULL) {        view->drawEntity(e);        offset+=e->getLength();        //RS_DEBUG->print("offset: %f\nlength was: %f", offset, e->getLength());    }    for (RS_Entity* e=nextEntity(RS2::ResolveNone);            e!=NULL;            e = nextEntity(RS2::ResolveNone)) {        view->drawEntityPlain(e, -offset);        offset+=e->getLength();        //RS_DEBUG->print("offset: %f\nlength was: %f", offset, e->getLength());    }}/**

⌨️ 快捷键说明

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