예제 #1
0
// general purpose facet-drop which calls xy_normal_length(), normal_length(), 
// and center_height() on the subclass
bool MillingCutter::facetDrop(CLPoint &cl, const Triangle &t) const { // Drop cutter at (cl.x, cl.y) against facet of Triangle t
    Point normal = t.upNormal(); // facet surface normal
    if ( isZero_tol( normal.z ) )  // vertical surface
        return false;  //can't drop against vertical surface
    assert( isPositive( normal.z ) );
    
    if ( ( isZero_tol(normal.x) ) && ( isZero_tol(normal.y) ) ) { // horizontal plane special case
        CCPoint cc_tmp( cl.x, cl.y, t.p[0].z, FACET);
        return cl.liftZ_if_inFacet(cc_tmp.z, cc_tmp, t);
    } else { // general case
        // plane containing facet:  a*x + b*y + c*z + d = 0, so
        // d = -a*x - b*y - c*z, where  (a,b,c) = surface normal
        double d = - normal.dot(t.p[0]);
        normal.normalize(); // make length of normal == 1.0
        Point xyNormal( normal.x, normal.y, 0.0);
        xyNormal.xyNormalize();
        // define the radiusvector which points from the cc-point to the cutter-center 
        Point radiusvector = this->xy_normal_length*xyNormal + this->normal_length*normal;
        CCPoint cc_tmp = cl - radiusvector; // NOTE xy-coords right, z-coord is not.
        cc_tmp.z = (1.0/normal.z)*(-d-normal.x*cc_tmp.x-normal.y*cc_tmp.y); // cc-point lies in the plane.
        cc_tmp.type = FACET;
        double tip_z = cc_tmp.z + radiusvector.z - this->center_height;
        return cl.liftZ_if_inFacet(tip_z, cc_tmp, t);
    }
}
예제 #2
0
// general purpose vertex-drop which delegates to this->height(r) of subclass 
bool MillingCutter::vertexDrop(CLPoint &cl, const Triangle &t) const {
    bool result = false;
    BOOST_FOREACH( const Point& p, t.p) {           // test each vertex of triangle
        double q = cl.xyDistance(p);                // distance in XY-plane from cl to p
        if ( q <= radius ) {                        // p is inside the cutter
            CCPoint cc_tmp(p, VERTEX);
            if ( cl.liftZ( p.z - this->height(q), cc_tmp ) )
                result = true;
        } 
    }
    return result;
}
예제 #3
0
// "dual" edge-drop problems
// cylinder: zero diam edge/ellipse, r-radius cylinder, find r-offset == cl  (ITO surface XY-slice is a circle)
// sphere: zero diam cylinder. ellipse around edge, find offset == cl (ITO surface slice is ellipse) (?)
// toroid: radius2 diam edge, radius1 cylinder, find radius1-offset-ellipse=cl (ITO surf slice is offset ellipse) (this is the offset-ellipse problem)
// cone: ??? (how is this an ellipse??)
bool MillingCutter::singleEdgeDrop(CLPoint& cl, const Point& p1, const Point& p2, double d) const {    
    Point v = p2 - p1; // vector along edge, from p1 -> p2
    Point vxy( v.x, v.y, 0.0);
    vxy.xyNormalize(); // normalized XY edge vector
    // figure out u-coordinates of p1 and p2 (i.e. x-coord in the rotated system)
    Point sc = cl.xyClosestPoint( p1, p2 );   
    assert( ( (cl-sc).xyNorm() - d ) < 1E-6 );
    // edge endpoints in the new coordinate system, in these coordinates, CL is at origo
    Point up1( (p1-sc).dot(vxy) , d, p1.z); // d, distance to line, is the y-coord in the rotated system
    Point up2( (p2-sc).dot(vxy) , d, p2.z);
    CC_CLZ_Pair contact = this->singleEdgeDropCanonical( up1, up2 ); // the subclass handles this
    CCPoint cc_tmp( sc + contact.first * vxy, EDGE); // translate back into original coord-system
    cc_tmp.z_projectOntoEdge(p1,p2);
    return cl.liftZ_if_InsidePoints( contact.second , cc_tmp , p1, p2);
}
예제 #4
0
CLPoint CCopasiSpringLayout::borderProjection(CLGraphicalObject* go, const CLPoint & p, double d)
{
  CLPoint center = go->getBoundingBox().getCenter();
  CLPoint diff = p - center;

  CLPoint ret;

  if (fabs(diff.getX()) * (fabs(go->getHeight()) * 0.5 + d) > fabs(diff.getY()) * (fabs(go->getWidth()) * 0.5 + d))
    {
      double f = (fabs(go->getWidth()) * 0.5 + d) / fabs(diff.getX());
      ret = center + diff * f;
    }
  else
    {
      double f = (fabs(go->getHeight()) * 0.5 + d) / fabs(diff.getY());
      ret = center + diff * f;
    }

  return ret;
}
예제 #5
0
파일: conecutter.cpp 프로젝트: play113/swer
// because this checks for contact with both the tip and the circular edge it is hard to move to the base-class
// we either hit the tip, when the slope of the plane is smaller than angle
// or when the slope is steep, the circular edge between the cone and the cylindrical shaft
bool ConeCutter::facetDrop(CLPoint &cl, const Triangle &t) const {
    bool result = false;
    Point normal = t.upNormal(); // facet surface normal    
    if ( isZero_tol( normal.z ) )  // vertical surface
        return false;  //can't drop against vertical surface
    
    if ( (isZero_tol(normal.x)) && (isZero_tol(normal.y)) ) {  // horizontal plane special case
        CCPoint cc_tmp( cl.x, cl.y, t.p[0].z, FACET_TIP );  // so any vertex is at the correct height
        return cl.liftZ_if_inFacet(cc_tmp.z, cc_tmp, t);
    } else {
        // define plane containing facet
        // a*x + b*y + c*z + d = 0, so
        // d = -a*x - b*y - c*z, where  (a,b,c) = surface normal
        double a = normal.x;
        double b = normal.y;
        double c = normal.z;
        double d = - normal.dot(t.p[0]); 
        normal.xyNormalize(); // make xy length of normal == 1.0
        // cylindrical contact point case
        // find the xy-coordinates of the cc-point
        CCPoint cyl_cc_tmp =  cl - radius*normal;
        cyl_cc_tmp.z = (1.0/c)*(-d-a*cyl_cc_tmp.x-b*cyl_cc_tmp.y);
        double cyl_cl_z = cyl_cc_tmp.z - length; // tip positioned here
        cyl_cc_tmp.type = FACET_CYL;
        
        // tip contact with facet
        CCPoint tip_cc_tmp(cl.x,cl.y,0.0);
        tip_cc_tmp.z = (1.0/c)*(-d-a*tip_cc_tmp.x-b*tip_cc_tmp.y);
        double tip_cl_z = tip_cc_tmp.z;
        tip_cc_tmp.type = FACET_TIP;
              
        result = result || cl.liftZ_if_inFacet( tip_cl_z, tip_cc_tmp, t);
        result = result || cl.liftZ_if_inFacet( cyl_cl_z, cyl_cc_tmp, t);
        return result; 
    }
}
예제 #6
0
// call vertex, facet, and edge drop methods on input Triangle t
bool MillingCutter::dropCutter(CLPoint &cl, const Triangle &t) const {
    bool facet, vertex, edge;
    /* // alternative ordering of the tests:
    if (cl.below(t))
        vertexDrop(cl,t);
        
    // optimisation: if we are now above the triangle we don't need facet and edge
    if ( cl.below(t) ) {
        facetDrop(cl,t); 
        edgeDrop(cl,t);
    }*/
    
    if (cl.below(t)) {
        facet = facetDrop(cl,t); // if we make contact with the facet...
        if (!facet) {            // ...then we will not hit an edge/vertex, so don't check for that
            vertex = vertexDrop(cl,t);
            if ( cl.below(t) ) {
                edge = edgeDrop(cl,t); 
            }
        }
    }
    
    return ( facet || vertex || edge ); 
}
// call vertex, facet, and edge drop methods on input Triangle t
bool MillingCutter::dropCutter(CLPoint &cl, const Triangle &t) const {
    bool facet, vertex, edge;
    /* // alternative ordering of the tests:
    if (cl.below(t))
        vertexDrop(cl,t);
        
    // optimisation: if we are now above the triangle we don't need facet and edge
    if ( cl.below(t) ) {
        facetDrop(cl,t); 
        edgeDrop(cl,t);
    }*/
    
    if (cl.below(t)) {
        facet = facetDrop(cl,t);
        if (!facet) {
            vertex = vertexDrop(cl,t);
            if ( cl.below(t) ) {
                edge = edgeDrop(cl,t);
            }
        }
    }
    
    return ( facet || vertex || edge ); 
}
예제 #8
0
// edge-drop function which calls the sub-class MillingCutter::singleEdgeDrop on each 
// edge of the input Triangle t.
bool MillingCutter::edgeDrop(CLPoint &cl, const Triangle &t) const {
    bool result = false;
    for (int n=0;n<3;n++) { // loop through all three edges
        int start=n;      // index of the start-point of the edge
        int end=(n+1)%3;  // index of the end-point of the edge
        const Point p1 = t.p[start];
        const Point p2 = t.p[end];
        if ( !isZero_tol( p1.x - p2.x) || !isZero_tol( p1.y - p2.y) ) {
            const double d = cl.xyDistanceToLine(p1,p2);
            if (d<=radius)  // potential contact with edge
                if ( this->singleEdgeDrop(cl,p1,p2,d) )
                    result=true;
        }
    }
    return result;
}
예제 #9
0
bool CompositeCutter::ccValidRadius(unsigned int n, CLPoint& cl) const {
    if (cl.cc->type == NONE)
        return false;
    double d = cl.xyDistance(*cl.cc);
    double lolimit;
    double hilimit;
    if (n==0)
        lolimit = - 1E-6;
    else
        lolimit = radiusvec[n-1] - 1E-6;
    hilimit = radiusvec[n]+1e-6; // FIXME: really ugly solution this one...
    if (d<lolimit)
        return false;
    else if (d>hilimit)
        return false;
    else
        return true;
}
예제 #10
0
// use OpenMP to share work between threads
void PointDropCutter::pointDropCutter1(CLPoint& clp) {
    nCalls = 0;
    int calls=0;
    std::list<Triangle>* tris;
    //tris=new std::list<Triangle>();
    tris = root->search_cutter_overlap( cutter, &clp );
    std::list<Triangle>::iterator it;
    for( it=tris->begin(); it!=tris->end() ; ++it) { // loop over found triangles  
        if ( cutter->overlaps(clp,*it) ) { // cutter overlap triangle? check
            if (clp.below(*it)) {
                cutter->dropCutter(clp,*it);
                ++calls;
            }
        }
    }
    delete( tris );
    nCalls = calls;
    return;
}
예제 #11
0
/*  
 *  Copyright 2010-2011 Anders Wallin (anders.e.e.wallin "at" gmail.com)
 *  
 *  This file is part of OpenCAMlib.
 *
 *  OpenCAMlib is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  OpenCAMlib 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 OpenCAMlib.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <sstream>
#include <string>

#include "compositecutter.hpp"
#include "numeric.hpp"
#include "cylcutter.hpp"
#include "ballcutter.hpp"
#include "bullcutter.hpp"
#include "conecutter.hpp"

namespace ocl
{

CompositeCutter::CompositeCutter() {
    radiusvec = std::vector<double>();
    cutter = std::vector<MillingCutter*>();
    radius=0;
    diameter=0;
}

// add cutter c which is valid until radius=r and height=z with z-offset zoff
void CompositeCutter::addCutter(MillingCutter& c, double r, double h, double zoff) {
    radiusvec.push_back(r);
    heightvec.push_back(h);
    cutter.push_back(&c);
    zoffset.push_back(zoff);
    if (r>radius) {
        radius = r;
        diameter = 2*r;
    }
    // update length also?
}



// this allows vertexDrop in the base-class to work as for other cutters
double CompositeCutter::height(double r) const {
    unsigned int idx = radius_to_index(r);
    return cutter[idx]->height(r) + zoffset[idx];
}

// return the width of the cutter at height h. 
double CompositeCutter::width(double h) const {
    unsigned int idx = height_to_index(h);
    // std::cout << "CompositeCutter::width( " << h << " ) idx=" << idx << " zoffset= " << zoffset[idx] << "\n";
    // std::cout << " width  =  " << cutter[idx]->width( h - zoffset[idx] ) << "\n";
    return cutter[idx]->width( h - zoffset[idx] );
}

unsigned int CompositeCutter::height_to_index(double h) const {
    for (unsigned int n=0; n<cutter.size(); ++n) {
        if ( validHeight(n,h) )
            return n;
    }
    // return the last cutter if we get here...
    return cutter.size()-1;
    std::cout << " Error, height= " << h << " has no index \n";
    assert(0);
    return 0;
}


unsigned int CompositeCutter::radius_to_index(double r) const {
    for (unsigned int n=0; n<cutter.size(); ++n) {
        if ( validRadius(n,r) )
            return n;
    }
    assert(0);
    return 0;
}

bool CompositeCutter::ccValidRadius(unsigned int n, CLPoint& cl) const {
    if (cl.cc->type == NONE)
        return false;
    double d = cl.xyDistance(*cl.cc);
    double lolimit;
    double hilimit;
    if (n==0)
        lolimit = - 1E-6;
    else
        lolimit = radiusvec[n-1] - 1E-6;
    hilimit = radiusvec[n]+1e-6; // FIXME: really ugly solution this one...
    if (d<lolimit)
        return false;
    else if (d>hilimit)
        return false;
    else
        return true;
}

bool CompositeCutter::ccValidHeight(unsigned int n, CCPoint& cc, const Fiber& f) const {
    //if (  ((cc.z-f.p1.z) >= 0.0)  && (n == height_to_index(cc.z-f.p1.z)) )
    if (  n == height_to_index(cc.z-f.p1.z) )
        return true;
    else
        return false;
}

// return true if height h belongs to cutter n
bool CompositeCutter::validHeight(unsigned int n, double h) const {
    double lolimit, hilimit;
    if (n==0)
        lolimit = -1E-6;
    else
        lolimit = heightvec[n-1] - 1E-6;
    hilimit = heightvec[n]+1e-6; // FIXME: really ugly solution this one...
    if ( (lolimit<=h) )
        if  (h<=hilimit)
            return true;
    return false;
}


bool CompositeCutter::validRadius(unsigned int n, double r) const {
    assert( r >= 0.0 );
    double lolimit, hilimit;
    if (n==0)
        lolimit = -1E-6;
    else
        lolimit = radiusvec[n-1] - 1E-6;
    hilimit = radiusvec[n]+1e-6; // FIXME: really ugly solution this one...
    if ( (lolimit<=r) )
        if  (r<=hilimit)
            return true;
    return false;
}

//********   facetDrop  ********************** */

// call facetDrop on each cutter and pick a valid cc-point
bool CompositeCutter::facetDrop(CLPoint &cl, const Triangle &t) const {
    bool result = false;
    for (unsigned int n=0; n<cutter.size(); ++n) { // loop through cutters
        CLPoint cl_tmp = cl + CLPoint(0,0,zoffset[n]);
        CCPoint* cc_tmp;
        if ( cutter[n]->facetDrop(cl_tmp, t) ) {
            assert( cl_tmp.cc != 0);
            if ( ccValidRadius(n,cl_tmp) ) { // cc-point is valid
                cc_tmp = new CCPoint(*cl_tmp.cc);
                if (cl.liftZ( cl_tmp.z - zoffset[n] )) { // we need to lift the cutter
                    cc_tmp->type = FACET;
                    cl.cc = cc_tmp;
                    result = true;
                } else {
                    delete cc_tmp;
                }
            }
        }
    }
    return result;
}

//********   edge **************************************************** */
bool CompositeCutter::edgeDrop(CLPoint &cl, const Triangle &t) const {
    bool result = false;
    for (unsigned int n=0; n<cutter.size(); ++n) { // loop through cutters
        CLPoint cl_tmp = cl + Point(0,0,zoffset[n]);
        CCPoint* cc_tmp;
        if ( cutter[n]->edgeDrop(cl_tmp,t) ) { // drop sub-cutter against edge
            if ( ccValidRadius(n,cl_tmp) ) { // check if cc-point is valid
                cc_tmp = new CCPoint(*cl_tmp.cc);
                if (cl.liftZ( cl_tmp.z - zoffset[n] ) ) { // we need to lift the cutter
                    cc_tmp->type = EDGE;
                    cl.cc = cc_tmp;
                    result = true;
                } else {
                    delete cc_tmp;
                }
            }
        }
    }
    return result;
}
예제 #12
0
// call facetDrop on each cutter and pick a valid cc-point
bool CompositeCutter::facetDrop(CLPoint &cl, const Triangle &t) const {
    bool result = false;
    for (unsigned int n=0; n<cutter.size(); ++n) { // loop through cutters
        CLPoint cl_tmp = cl + CLPoint(0,0,zoffset[n]);
        CCPoint* cc_tmp;
        if ( cutter[n]->facetDrop(cl_tmp, t) ) {
            assert( cl_tmp.cc != 0);
            if ( ccValidRadius(n,cl_tmp) ) { // cc-point is valid
                cc_tmp = new CCPoint(*cl_tmp.cc);
                if (cl.liftZ( cl_tmp.z - zoffset[n] )) { // we need to lift the cutter
                    cc_tmp->type = FACET;
                    cl.cc = cc_tmp;
                    result = true;
                } else {
                    delete cc_tmp;
                }
            }
        }
    }
    return result;
}
예제 #13
0
void CQGLViewport::updateScrollbars()
{
  // reset the scollbar range
  // TODO check te setting for the scroll range since there seem to be some
  // error messages
  // disconnect the scrollbar listeners and handle the update so that the GL
  // window is only redrawn once
  double zoom = this->mpNetworkPainter->getZoomFactor();
  CLPoint max = this->mpNetworkPainter->getGraphMax();
  CLPoint min = this->mpNetworkPainter->getGraphMin();
  double graphWidth = (max.getX() - min.getX()) * zoom;
  double graphHeight = (max.getY() - min.getY()) * zoom;
  double rectangleHeight = this->contentsRect().height();
  double rectangleWidth = this->contentsRect().width();

  if (graphHeight < rectangleHeight)
    {
      this->mpVerticalScrollbar->hide();
      this->mpVerticalScrollbar->setValue(0);
    }
  else
    {
      this->mpVerticalScrollbar->setPageStep(rectangleHeight);
      this->mpVerticalScrollbar->setRange(0, (unsigned int)(graphHeight - rectangleHeight));
      this->mpVerticalScrollbar->show();
      this->mpNetworkPainter->update();
    }

  if (graphWidth < rectangleWidth)
    {
      this->mpHorizontalScrollbar->hide();
      this->mpHorizontalScrollbar->setValue(0);
    }
  else
    {
      this->mpHorizontalScrollbar->setPageStep(rectangleWidth);
      this->mpHorizontalScrollbar->setRange(0, (unsigned int)(graphWidth - rectangleWidth));
      this->mpHorizontalScrollbar->show();
      this->mpNetworkPainter->update();
    }
}
예제 #14
0
void CCopasiSpringLayout::finalizeState()
{
  unsigned int i;

  //update the positions of the dependent glyphs
  //this can be done here since we assume that those glyphs
  //do not affect the layout.
  std::vector<CoordinateRelation>::const_iterator it, itEnd = mFixedRelations.end();

  for (it = mFixedRelations.begin(); it != itEnd; ++it)
    it->target->setPosition(it->source->getPosition() + it->diff);

  //for now, only create curves for the reaction glyphs
  for (i = 0; i < mpLayout->getListOfReactionGlyphs().size() ; ++i)
    {
      CLReactionGlyph* pRG = mpLayout->getListOfReactionGlyphs()[i];

      //Determine the average position of substrates and products, giving less weight to side reactants
      CLPoint s, p;
      double s_c = 0; double p_c = 0;
      unsigned int j, jmax = pRG->getListOfMetabReferenceGlyphs().size();

      for (j = 0; j < jmax; ++j)
        {
          if (pRG->getListOfMetabReferenceGlyphs()[j]->getRole() == CLMetabReferenceGlyph::SUBSTRATE)
            {
              s_c += 1.0;
              s = s + pRG->getListOfMetabReferenceGlyphs()[j]->getMetabGlyph()->getBoundingBox().getCenter();
            }

          if (pRG->getListOfMetabReferenceGlyphs()[j]->getRole() == CLMetabReferenceGlyph::SIDESUBSTRATE)
            {
              s_c += 0.1;
              s = s + pRG->getListOfMetabReferenceGlyphs()[j]->getMetabGlyph()->getBoundingBox().getCenter() * 0.1;
            }

          if (pRG->getListOfMetabReferenceGlyphs()[j]->getRole() == CLMetabReferenceGlyph::PRODUCT)
            {
              p_c += 1.0;
              p = p + pRG->getListOfMetabReferenceGlyphs()[j]->getMetabGlyph()->getBoundingBox().getCenter();
            }

          if (pRG->getListOfMetabReferenceGlyphs()[j]->getRole() == CLMetabReferenceGlyph::SIDEPRODUCT)
            {
              p_c += 0.1;
              p = p + pRG->getListOfMetabReferenceGlyphs()[j]->getMetabGlyph()->getBoundingBox().getCenter() * 0.1;
            }
        }

      if (s_c > 0)
        s = s * (1 / s_c);
      else
        s = pRG->getPosition();

      if (p_c > 0)
        p = p * (1 / p_c);
      else
        p = pRG->getPosition();

      CLPoint dir = p - s; //overall direction of reaction

      if (dir.getX() == 0 && dir.getY() == 0)
        dir = CLPoint(1, 0);

      CLPoint ortho_dir = CLPoint(dir.getY(), -dir.getX());
      ortho_dir.scale(1 / sqrt(pow(ortho_dir.getX(), 2) + pow(ortho_dir.getY(), 2)));

      CLPoint reaction_s = pRG->getPosition() - (dir * 0.05);
      CLPoint reaction_p = pRG->getPosition() + (dir * 0.05);
      CLPoint reaction_m1 = pRG->getPosition() + ortho_dir * 10;
      CLPoint reaction_m2 = pRG->getPosition() - ortho_dir * 10;

      pRG->getCurve().clear();
      pRG->getCurve().addCurveSegment(CLLineSegment(reaction_s, reaction_p));

      for (j = 0; j < jmax; ++j)
        {
          //here we need to generate the curves for the MetabReferenceGlyphs.
          //we will need to consider the size of the glyphs, role of the metab in the reaction, etc.
          //For now, only a primitive implementation: TODO: improve
          CLMetabReferenceGlyph* pMRG = pRG->getListOfMetabReferenceGlyphs()[j];
          double direction;
          double modifierLength = -0.2;

          switch (pMRG->getRole())
            {
              case CLMetabReferenceGlyph::SUBSTRATE :
              case CLMetabReferenceGlyph::SIDESUBSTRATE :
              {
                direction = -0.1;
                CLPoint metabPoint = borderProjection(pMRG->getMetabGlyph(), reaction_s + dir * direction /*(modifierLength * 1.5)*/, 5);
                pMRG->getCurve().clear();
                pMRG->getCurve().addCurveSegment(CLLineSegment(reaction_s,
                                                 metabPoint,
                                                 reaction_s + dir * direction,
                                                 (reaction_s + dir * (direction * 1.5) + metabPoint) * 0.5));
              }
              break;

              case CLMetabReferenceGlyph::PRODUCT :
              case CLMetabReferenceGlyph::SIDEPRODUCT :
              {
                direction = 0.1;
                CLPoint metabPoint = borderProjection(pMRG->getMetabGlyph(), reaction_p + dir * direction /*(modifierLength * 1.5)*/, 5);
                pMRG->getCurve().clear();
                pMRG->getCurve().addCurveSegment(CLLineSegment(reaction_p,
                                                 metabPoint,
                                                 reaction_p + dir * direction,
                                                 (reaction_p + dir * (direction * 1.5) + metabPoint) * 0.5));
              }
              break;

              default:
              {
                CLPoint reactionPoint;

                if (ortho_dir.dot(pRG->getPosition() - pMRG->getMetabGlyph()->getPosition()) < 0)
                  {
                    direction = +10.0;
                    reactionPoint = reaction_m1;
                  }
                else
                  {
                    direction = -10.0;
                    reactionPoint = reaction_m2;
                  }

                CLPoint metabPoint = borderProjection(pMRG->getMetabGlyph(), reactionPoint + dir * 0 * direction /*(modifierLength * 1.5)*/, 5);
                pMRG->getCurve().clear();
                pMRG->getCurve().addCurveSegment(CLLineSegment(metabPoint,
                                                 reactionPoint,
                                                 (reactionPoint + dir * (0 * direction * 1.5) + metabPoint) * 0.5,
                                                 reactionPoint + ortho_dir * direction));
              }
            }
        }
    }

  //rearrange the text boxes
  //TODO

  //calculate bounding box for the layout, or recenter the layout
  //for (i = 0; i < mpLayout->getListOfSpeciesGlyphs().size() ; ++i)

  const CLBoundingBox &bounds =  mpLayout->calculateBoundingBox();

  mpLayout->setDimensions(CLDimensions(bounds.getPosition().getX() + bounds.getDimensions().getWidth(), bounds.getPosition().getY() + bounds.getDimensions().getHeight()));
}
예제 #15
0
void CQGLViewport::slotHValueChanged(int value)
{
  CLPoint p = this->mpNetworkPainter->getGraphMin();
  double zoom = this->mpNetworkPainter->getZoomFactor();
  this->mpNetworkPainter->setCurrentPositionX((double)(p.getX() + value / zoom));
}
예제 #16
0
void CCopasiSpringLayout::finalizeState()
{
  unsigned int i;

  //update the positions of the dependent glyphs
  //this can be done here since we assume that those glyphs
  //do not affect the layout.
  updateFixedRelations();

  //for now, only create curves for the reaction glyphs
  for (i = 0; i < mpLayout->getListOfReactionGlyphs().size() ; ++i)
    {
      CLReactionGlyph* pRG = &mpLayout->getListOfReactionGlyphs()[i];

      //Determine the average position of substrates and products, giving less weight to side reactants
      CLPoint s, p;
      double s_c = 0; double p_c = 0;
      unsigned int j, jmax = pRG->getListOfMetabReferenceGlyphs().size();

      for (j = 0; j < jmax; ++j)
        {
          if (pRG->getListOfMetabReferenceGlyphs()[j].getFunctionalRole() == CLMetabReferenceGlyph::SUBSTRATE)
            {
              CLMetabGlyph* metabGlyph = pRG->getListOfMetabReferenceGlyphs()[j].getMetabGlyph();

              if (metabGlyph != NULL)
                {
                  s_c += 1.0;
                  s = s + metabGlyph->getBoundingBox().getCenter();
                }
            }

          if (pRG->getListOfMetabReferenceGlyphs()[j].getFunctionalRole() == CLMetabReferenceGlyph::SIDESUBSTRATE)
            {
              CLMetabGlyph* metabGlyph = pRG->getListOfMetabReferenceGlyphs()[j].getMetabGlyph();

              if (metabGlyph != NULL)
                {
                  s_c += 0.1;
                  s = s + metabGlyph->getBoundingBox().getCenter() * 0.1;
                }
            }

          if (pRG->getListOfMetabReferenceGlyphs()[j].getFunctionalRole() == CLMetabReferenceGlyph::PRODUCT)
            {
              CLMetabGlyph* metabGlyph = pRG->getListOfMetabReferenceGlyphs()[j].getMetabGlyph();

              if (metabGlyph != NULL)
                {
                  p_c += 1.0;
                  p = p + metabGlyph->getBoundingBox().getCenter();
                }
            }

          if (pRG->getListOfMetabReferenceGlyphs()[j].getFunctionalRole() == CLMetabReferenceGlyph::SIDEPRODUCT)
            {
              CLMetabGlyph* metabGlyph = pRG->getListOfMetabReferenceGlyphs()[j].getMetabGlyph();

              if (metabGlyph != NULL)
                {

                  p_c += 0.1;
                  p = p + metabGlyph->getBoundingBox().getCenter() * 0.1;
                }
            }
        }

      CLPoint position = pRG->getPosition();

      if (position.getX() == 0 && position.getY() == 0
          && pRG->getDimensions().getWidth() == 0
          && pRG->getDimensions().getHeight() == 0
          && pRG->getCurve().getNumCurveSegments() > 0)
        {
          position = pRG->getCurve().getCurveSegments()[0].getStart();
          pRG->setPosition(position);
        }

      if (s_c > 0)
        s = s * (1 / s_c);
      else
        {
          s = position;
        }

      if (p_c > 0)
        p = p * (1 / p_c);
      else
        p = position;

      CLPoint dir = p - s; //overall direction of reaction

      if (dir.getX() == 0 && dir.getY() == 0)
        dir = CLPoint(1, 0);

      CLPoint ortho_dir = CLPoint(dir.getY(), -dir.getX());
      ortho_dir.scale(1 / sqrt(pow(ortho_dir.getX(), 2) + pow(ortho_dir.getY(), 2)));

      CLPoint reaction_s = position - (dir * 0.05);
      CLPoint reaction_p = position + (dir * 0.05);
      CLPoint reaction_m1 = position + ortho_dir * 10;
      CLPoint reaction_m2 = position - ortho_dir * 10;

      pRG->getCurve().clear();
      pRG->getCurve().addCurveSegment(CLLineSegment(reaction_s, reaction_p));

      for (j = 0; j < jmax; ++j)
        {
          //here we need to generate the curves for the MetabReferenceGlyphs.
          //we will need to consider the size of the glyphs, role of the metab in the reaction, etc.
          //For now, only a primitive implementation: TODO: improve
          CLMetabReferenceGlyph* pMRG = &pRG->getListOfMetabReferenceGlyphs()[j];
          double direction;
          //double modifierLength = -0.2;

          switch (pMRG->getFunctionalRole())
            {
              case CLMetabReferenceGlyph::SUBSTRATE :
              case CLMetabReferenceGlyph::SIDESUBSTRATE :
              {
                direction = -0.1;
                CLPoint metabPoint = borderProjection(pMRG->getMetabGlyph(), reaction_s + dir * direction /*(modifierLength * 1.5)*/, 5);
                pMRG->getCurve().clear();
                pMRG->getCurve().addCurveSegment(CLLineSegment(reaction_s,
                                                 metabPoint,
                                                 reaction_s + dir * direction,
                                                 (reaction_s + dir * (direction * 1.5) + metabPoint) * 0.5));
              }
              break;

              case CLMetabReferenceGlyph::PRODUCT :
              case CLMetabReferenceGlyph::SIDEPRODUCT :
              {
                direction = 0.1;
                CLPoint metabPoint = borderProjection(pMRG->getMetabGlyph(), reaction_p + dir * direction /*(modifierLength * 1.5)*/, 5);
                pMRG->getCurve().clear();
                pMRG->getCurve().addCurveSegment(CLLineSegment(reaction_p,
                                                 metabPoint,
                                                 reaction_p + dir * direction,
                                                 (reaction_p + dir * (direction * 1.5) + metabPoint) * 0.5));
              }
              break;

              default:
              {
                CLPoint reactionPoint;

                if (pMRG->getMetabGlyph() && ortho_dir.dot(pRG->getPosition() - pMRG->getMetabGlyph()->getPosition()) < 0)
                  {
                    direction = +10.0;
                    reactionPoint = reaction_m1;
                  }
                else
                  {
                    direction = -10.0;
                    reactionPoint = reaction_m2;
                  }

                CLPoint metabPoint = borderProjection(pMRG->getMetabGlyph(), reactionPoint + dir * 0 * direction /*(modifierLength * 1.5)*/, 5);
                pMRG->getCurve().clear();
                pMRG->getCurve().addCurveSegment(CLLineSegment(metabPoint,
                                                 reactionPoint,
                                                 (reactionPoint + dir * (0 * direction * 1.5) + metabPoint) * 0.5,
                                                 reactionPoint + ortho_dir * direction));
              }
            }
        }
    }

  //update the curves in the general glyph
  for (i = 0; i < mpLayout->getListOfGeneralGlyphs().size() ; ++i)
    {
      CLGeneralGlyph* pGG = &mpLayout->getListOfGeneralGlyphs()[i];

      size_t j;

      for (j = 0; j < pGG->getListOfReferenceGlyphs().size(); ++j)
        {
          CLReferenceGlyph* pRG = &pGG->getListOfReferenceGlyphs()[j];

          if (pRG->getCurve().getNumCurveSegments() == 0) continue;

          CLPoint refPoint = borderProjection(pRG->getTargetGlyph(), pRG->getBoundingBox().getCenter(), 5);
          pRG->getCurve().clear();
          pRG->getCurve().addCurveSegment(CLLineSegment(refPoint, pRG->getBoundingBox().getCenter()));
        }
    }

  //calculate bounding box for the layout, or recenter the layout
  mpLayout->calculateAndAssignBounds();
}