Esempio n. 1
0
/* 
 * Draw the stool
 * Stool's base height is 0 (on the floor)
 * Dimensions:
 *  Seat diameter: 11 3/4 "
 *  Width: 14 5/8 "
 *  Depth: 19 5/8 "
 *  Min. seat height: 24 3/4 "
 *  Max. seat height: 29 1/8 "
 */
void Stool::draw(MatrixStack &mViewStack) {
	mViewStack.push();
	
	// position stool with feet on the floor
	mViewStack.active = glm::translate(mViewStack.active, glm::vec3(0.0f, STOOL_HEIGHT, 0.0f));
	
	// seat and stem rendering
	mViewStack.push();
	// used in height adjustment controls
	mViewStack.active = glm::translate(mViewStack.active, glm::vec3(0.0f, heightAdjust, 0.0f));
	drawSeatAndStem(mViewStack);
	mViewStack.pop();

	// leg rendering
	drawLeg(mViewStack, 0);
	drawLeg(mViewStack, 90);
	drawLeg(mViewStack, 180);
	drawLeg(mViewStack, 270);

	// draw lower ring
	drawRing(mViewStack);

	// draw upper disks
	drawDisk(mViewStack, TOP_DISK_RAD, 23.75f);
	drawDisk(mViewStack, BOT_DISK_RAD, 21.25f);

	mViewStack.pop();
}
Esempio n. 2
0
void BitObject::drawOutline(Image<T_or_RGB>& img, 
                            const T_or_RGB& color,
                            float opacity)
{
  ASSERT(isValid());
  ASSERT(img.initialized());
  float op2 = 1.0F - opacity;

  Dims d = img.getDims();
  Image<byte> mask = getObjectMask();

  // rescale if needed
  if (d != itsImageDims)
    mask = rescaleNI(mask, d.w(), d.h());

  // object-shaped drawing
  int thick = 1;
  Image<byte> om(mask);
  om = contour2D(om);       // compute binary contour image
  const int w = img.getWidth();
  const int h = img.getHeight();
  Point2D<int> ppp;
  for (ppp.j = 0; ppp.j < h; ppp.j ++)
    for (ppp.i = 0; ppp.i < w; ppp.i ++)
      if (om.getVal(ppp.i, ppp.j))  // got a contour point -> draw here
        drawDisk(img, ppp, thick, T_or_RGB(img.getVal(ppp) * op2 + color * opacity));  // small disk for each point

} // end drawOutline
Esempio n. 3
0
void Simulation::refresh()
{
    SDL_RenderClear(renderer);
    for (Particle *p : particles) {
        SDL_SetRenderDrawColor(renderer, p->getR(), p->getG(),
                               p->getB(), 255);
        drawDisk(p->getX(), p->getY(), p->getRadius());
        resetBackgroundColor();
    }

    SDL_RenderPresent(renderer);
}
Esempio n. 4
0
//----------------------------------------------------------------------------------------------------------------------
void CTRNNViz::drawNeuron(int i, const CTRNN* ctrnn, float inner, float outer)
{
    // white background
    glColor3f(1,1,1);
    drawDisk(outer, 0.0, 32, 1);

    // disk size indicating output value
    ci::Color col = ctrnn->getState(i) > 0 ? ci::Color(0,0,0) : ci::Color(235.0/255.0, 0.0/255.0, 103.0/255.0);
    if (ctrnn->getOutput(i) < 0) col = ci::Color(235.0/255.0, 0.0/255.0, 103.0/255.0);
    ci::gl::color(col);
    drawDisk(inner * clamp(getOutputNorm(i, ctrnn), 0.0, 1.0), 0.0, 32, 1);

    // ring size indicating external input value
    //glColor3f(181.0/255.0, 206.0/255.0, 26.0/255.0);
    col = ctrnn->getExternalInput(i) > 0 ? ci::Color(185/255.0, 185/255.0, 185/255.0) : ci::Color(235.0/255.0, 205.0/255.0, 221.0/255.0);
    ci::gl::color(col);
    float width = radiansToDegrees(ctrnn->getExternalInput(i) * TWO_PI);
    dmx::drawPartialDisk(inner, outer, 32, 1, 0, width, GLU_FILL);
    glColor3f(0,0,0);
    ci::gl::drawStrokedCircle(ci::Vec2f(0,0), outer, 32);
    ci::gl::drawStrokedCircle(ci::Vec2f(0,0), inner, 32);
}
Esempio n. 5
0
void QwtPieCurve::draw(QPainter *painter, const QwtScaleMap &xMap,
                       const QwtScaleMap &yMap, int from, int to) const {
  int size = dataSize();
  if (!painter || size <= 0)
    return;

  if (to < 0)
    to = size - 1;

  if (size > 1)
    drawSlices(painter, xMap, yMap, from, to);
  else
    drawDisk(painter, xMap, yMap);
}
Esempio n. 6
0
void Extract::paintGL() {
  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

  glLoadIdentity();

  // light sources
  glLightfv(GL_LIGHT0, GL_POSITION, xlight0_pos);
  //glLightfv(GL_LIGHT1, GL_POSITION, light1_pos);

  Point3D b1, b2;

  // contents, if necessary
  const GLfloat xglwater[] = { beakerRed, beakerGreen, beakerBlue, 
			       beakerAlpha };
  const GLfloat xgloil[] = { oilRed, oilGreen, oilBlue, oilAlpha };
  const GLfloat vglcyl[] = { 0.0, 0.0, 1.0, 0.4 };

  // no animation
  if (running == false) {
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, xglwater);
    glMaterialfv(GL_FRONT, GL_SPECULAR, xglwater);
    glMaterialfv(GL_FRONT, GL_SHININESS, xgldull);
    b1.setXYZ(0.0,-1.25,-10.0);
    b2.setXYZ(0.0,-4.75,-10.0);
    drawCylinder(b1,b2,1.9);
    drawDisk(b2,1.95);

    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, xgloil);
    glMaterialfv(GL_FRONT, GL_SPECULAR, xgloil);
    glMaterialfv(GL_FRONT, GL_SHININESS, xgldull);
    b1.setXYZ(0.0,-1.25 + beakerHeight,-10.0);
    b2.setXYZ(0.0,-1.25,-10.0);
    drawCylinder(b1,b2,1.9);
    drawDisk(b2,1.95);
  }

  // flask
  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, xglass);
  glMaterialfv(GL_FRONT, GL_SPECULAR, xglwhite);
  glMaterialfv(GL_FRONT, GL_SHININESS, xglpolished);
  b1.setXYZ(0.0,2.5,-10.0);
  b2.setXYZ(0.0,-5.0,-10.0);
  drawCylinder(b1,b2,2.0);

  // pedestal
  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, xglblack);
  glMaterialfv(GL_FRONT, GL_SPECULAR, xglwhite);
  glMaterialfv(GL_FRONT, GL_SHININESS, xglpolished);
  b1.setXYZ(0.0,-5.0,-10.0);
  b2.setXYZ(0.0,-6.0,-10.0);
  drawCylinder(b1,b2,-3.0);
  // pedestal indicator
  if (!running) {
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, xglwhite);
  } else {
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, xglblue);
  }
  glMaterialfv(GL_FRONT, GL_SPECULAR, xglwhite);
  glMaterialfv(GL_FRONT, GL_SHININESS, xglpolished);
  b1.setXYZ(0.0,-5.5,-7.0);
  drawSphere(b1,0.25);  

  // floor
  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, xglfloor);
  glMaterialfv(GL_FRONT, GL_SPECULAR, xglwhite);
  glMaterialfv(GL_FRONT, GL_SHININESS, xglpolished);
  b1.setXYZ(0.0,-6.0,-10.0);
  drawDisk(b1,100.0);
}
Esempio n. 7
0
// ######################################################################
Image<byte> getFoeDots
(uint step, bool haveMotion, bool  haveTempSGrad, bool haveSpatSGrad,
 float dx, float dy, float dotOrgDSize)
{
  //if(step > NFRAME) return Image<byte>();

  Image<byte> temp(WIDTH, HEIGHT, ZEROS);

  float orgDotSize = 1.0;

  // create random dot initially
  if(step == 0)
    {
      dots.resize(DOT_NUM); dotSizes.resize(DOT_NUM);
      for(uint i = 0; i < DOT_NUM; i++)
        {
          dots[i] = Point2D<float>
            (WIDTH  * double(rand())/(RAND_MAX + 1.0),
             HEIGHT * double(rand())/(RAND_MAX + 1.0));

          // just do it in order to get identical average size
          //float range = MAX_DOT_SIZE - MIN_DOT_SIZE;
          //dotSizes[i] = i*range/(DOT_NUM-1.0)+ double(MIN_DOT_SIZE); 
          dotSizes[i] = orgDotSize; 
        }
    }

  // check for out-of-bounds dot needed to be shown
  for(uint i = 0; i < DOT_NUM; i++)
    {
      // NOTE: can also kill dots randomly before going out of the image
      // NOTE: how about adding new dots in the FOE quadrants
      if(!temp.getBounds().contains(Point2D<int>(dots[i].i, dots[i].j))) 
        {
          dots[i] = Point2D<float>
            (WIDTH  * double(rand())/(RAND_MAX + 1.0),
             HEIGHT * double(rand())/(RAND_MAX + 1.0) );

          // keep the sizes or 1.0?
          dotSizes[i] = orgDotSize; 
        }
    }

  // modify sizes according to rules
  for(uint i = 0; i < DOT_NUM; i++)
    {
      if(haveTempSGrad && haveSpatSGrad)
        {
          float dist = sqrt(pow((dots[i].i - FOE_X), 2.0) + 
                            pow((dots[i].j - FOE_Y), 2.0)  ); 
          if(haveMotion)
            {
              dotSizes[i] = dotOrgDSize * dist;
            }
          // growing, FOE coherent, but not moving 
          else
            {
              if(step == 0)
                {
                  dotSizes[i] = dotOrgDSize * dist;
                }
              else
                {
                  // increase until ABS_MAX_DSIZE, then stop
                  if(dotSizes[i] < ABS_MAX_DSIZE)
                    {
                      dotSizes[i] = (1.0 + DOT_DSIZE) *
                        dotOrgDSize * dist;
                    }
                  // else dot size stays the same
                }
            }
        }
      else if(haveTempSGrad && !haveSpatSGrad)
        {
          // all dot have same size just increase 
          float ds = MAX_DOT_SIZE - MIN_DOT_SIZE;
          dotSizes[i] = step*ds/(NFRAME - 1.0)+ double(MIN_DOT_SIZE); 
        }
      else if(!haveTempSGrad && haveSpatSGrad)
        {
          float dist = sqrt(pow((dots[i].i - FOE_X), 2.0) + 
                            pow((dots[i].j - FOE_Y), 2.0)  ); 
          dotSizes[i] = dotOrgDSize * dist;
        }
      // else just keep size 
    }

  // move the dots if needed
  if(haveMotion)
    for(uint i = 0; i < DOT_NUM; i++)
      {
        dots[i] = Point2D<float>
          (dots[i].i + DOT_VEL * (dots[i].i - FOE_X),
           dots[i].j + DOT_VEL * (dots[i].j - FOE_Y));
      }

  // add lateral motion
  if(dx != 0.0 || dy != 0.0)
    for(uint i = 0; i < DOT_NUM; i++)
      {
        dots[i] = Point2D<float>(dots[i].i + dx, dots[i].j + dy);
      }

  // finally draw the dots
  for(uint i = 0; i < DOT_NUM; i++)
    {
      //LINFO("loc: %10.3f %10.3f: size: %7.3f", 
      //      dots[i].i, dots[i].j, dotSizes[i]);
      drawDisk(temp,Point2D<int>(dots[i].i, dots[i].j),dotSizes[i],byte(255));
      //temp.setVal(dots[i].i, dots[i].j, byte(128));
    }

  // draw the FOE
  //drawDisk(temp,Point2D<int>(FOE_X,FOE_Y),2,byte(128));    

  return temp;
}
Esempio n. 8
0
// ######################################################################
Image<byte> getPlanarMotionStimuli
(Image<byte> temp, uint step, float dx, float dy)
{
  //if(step > NFRAME) return Image<byte>();

  uint dotNum = 200;//200;//DOT_NUM;

  float orgDotSize = 1.0;

  // create random dot initially
  if(step == 0)
    {
      pdots.resize(dotNum); pdotSizes.resize(dotNum);
      for(uint i = 0; i < dotNum; i++)
        {
          pdots[i] = Point2D<float>
            (WIDTH  * double(rand())/(RAND_MAX + 1.0),
             HEIGHT * double(rand())/(RAND_MAX + 1.0));
          pdotSizes[i] = orgDotSize; 
        }
    }
  
  // check for out-of-bounds dot needed to be shown
  for(uint i = 0; i < dotNum; i++)
    {
      // NOTE: can also kill dots randomly before going out of the image
      if(!temp.getBounds().contains(Point2D<int>(pdots[i].i, pdots[i].j))) 
        {
          float srx = 0.0;   float sry = 0.0;
          float rx  = WIDTH; float ry  = HEIGHT;
          if(dx < 0.0)     { srx = 7.0*WIDTH/8.0; rx  = WIDTH/8; }
          else if(dx > 0.0){ srx = 0.0;           rx  = WIDTH/8; }
          
          if(dy < 0.0)     { sry = 7.0*HEIGHT/8.0; ry  = HEIGHT/8; }
          else if(dy > 0.0){ sry = 0.0;            ry  = HEIGHT/8; }

          float sx = rx * double(rand())/(RAND_MAX + 1.0) + srx; 
          float sy = ry * double(rand())/(RAND_MAX + 1.0) + sry;
          
          pdots[i] = Point2D<float>(sx,sy);
          pdotSizes[i] = orgDotSize; 
          LDEBUG("new dots[%3d]: %7.3f %7.3f", i, sx, sy);
        }
      else
        {
          Point2D<int> pt(pdots[i].i, pdots[i].j);
          LDEBUG("[%3d] it's ok: (%7.3f %7.3f) -> %3d %3d", 
                 i, pdots[i].i, pdots[i].j, pt.i, pt.j);
        }
    }

  // planar motion
  if(dx != 0.0 || dy != 0.0)
    for(uint i = 0; i < dotNum; i++)
      {
        pdots[i] = Point2D<float>(pdots[i].i + dx, 
                                  pdots[i].j + dy);
      }

  // finally draw the dots
  for(uint i = 0; i < dotNum; i++)
    {
      LDEBUG("[%d] loc: %10.3f %10.3f: size: %7.3f", 
             i, pdots[i].i, pdots[i].j, pdotSizes[i]);
      drawDisk(temp,Point2D<int>(pdots[i].i, pdots[i].j),
               pdotSizes[i],byte(255));
      //temp.setVal(pdots[i].i, pdots[i].j, byte(128));
    }
  return temp;
}
Esempio n. 9
0
//----------------------------------------------------------------------------------------------------------------------
void SMCEnvironmentViz::update()
{
  glPushAttrib(GL_LIGHTING);
  glDisable(GL_LIGHTING);

  for(int i = 0; i < m_environment->getObjects().size(); i++)
  {
    const Positionable& obj = *m_environment->getObjects()[i];
    if(obj.isVisible())
    {
      ci::gl::color(obj.getColor());
      
      // Object specific collision detection
      if(obj.getType() == Positionable::kObj_Line)
      {
        const Line& line = (Line&)obj;
        ci::gl::drawLine(line.getStart(), line.getEnd());
      }
      else if (obj.getType() == Positionable::kObj_Triangle)
      {
        const Triangle& tri = (Triangle&)obj;        
        drawTriangle(ci::Vec3f(tri.p1), ci::Vec3f(tri.p2), ci::Vec3f(tri.p3));
      }
      else if (obj.getType() == Positionable::kObj_Circle)
      {
        const Circle& circle = (Circle&)obj;        
        ci::gl::drawSolidCircle(circle.getPosition(), circle.getRadius(), 32);
      }
      else if (obj.getType() == Positionable::kObj_Torus)
      {
        // Width specifies inflection points. For drawing we use the "half width at tenth of maximum"
        const Torus& t = (Torus&)obj;
        const ci::Vec2f& p = t.getPosition();
        glPushMatrix();
        glTranslatef(p.x, p.y, 0);
        //ci::gl::drawStrokedCircle(t.getPosition(), t.getRadius() - 2.15 * t.getWidth(), 32);
        //ci::gl::drawStrokedCircle(t.getPosition(), t.getRadius() + 2.15 * t.getWidth(), 32);
        //glColor3f(1,0,0);
        drawDisk(t.getRadius() + 2.15 * t.getWidth(), t.getRadius() - 2.15 * t.getWidth(), 32, 2, GLU_FILL);
        glPopMatrix();
      }
      else if (obj.getType() == Positionable::kObj_Gradient)
      {
        const Gradient& g = (Gradient&)obj;
        const ci::Vec2f& p = g.getPosition();
        ci::ColorA c =  ci::ColorA(1,1,1,1);
        glPushMatrix();
        glTranslatef(p.x, p.y, 0);
        drawRadialGradient(obj.getColor(), c, 32, g.getRadius());
        //glColor3f(0.9,0.9,0.9);
        //drawDisk(g.getRadius(), 0, 32, 2, GLU_SILHOUETTE);
        glPopMatrix();
      }
      else if (obj.getType() == Positionable::kObj_Gaussian)
      {
        const Gaussian& gaus = (Gaussian&)obj;        
        drawGaussian(gaus);
      }
      
#if DMX_ENV_DRAW_POS
      dmx::drawPoint(ci::Vec3f(obj.getPosition()), 4);
#endif
    }
  }
  
  glPopAttrib();
}
Esempio n. 10
0
//----------------------------------------------------------------------------------------------------------------------
void SMCAgentViz::update()
{
  glDisable(GL_DEPTH_TEST);
  
  // data
  const ci::Vec2f& pos = m_agent->getPosition();
  float angle = m_agent->getAngle();
  
  // Update trajectory
  if(!m_paused && m_steps % 2 == 0){
    m_traj.push_back(pos);
  
    if(m_traj.size() >= 800)
    {
      m_traj.pop_front();
    }
  }
  
  m_steps++;
  
  // pose
  m_pTM->setToIdentity();  
  m_pTM->setTranslate(ci::Vec3f(pos));  
  m_pTM->rotate(ci::Vec3f(0.0f, 0.0f, 1.0f), angle);

  NodeGroup::update();
  
  // draw
  glPushAttrib(GL_LIGHTING);
  glDisable(GL_LIGHTING);
  
  // Trajectory
  ci::ColorA trajCol (235.0/255.0, 89.0/255.0, 55.0/255.0, 1.0);
  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_COLOR_ARRAY);
  int numPoints =  m_traj.size();
  float lineVerts[numPoints*2];
  float colors[numPoints*4];
  glVertexPointer(2, GL_FLOAT, 0, lineVerts); // 2d positions
  glColorPointer(4, GL_FLOAT, 0, colors);     // 4d colors
  
  for(size_t i = 0; i < numPoints; i++)
  {
    lineVerts[i*2 + 0] = m_traj[i].x;
    lineVerts[i*2 + 1] = m_traj[i].y;
    float a = (float)i / (float)numPoints;
    
    colors[i*4 + 0] = trajCol[0];
    colors[i*4 + 1] = trajCol[1];
    colors[i*4 + 2] = trajCol[2];
    colors[i*4 + 3] = a;
  }
  glLineWidth(2.0);
  glDrawArrays( GL_LINE_STRIP, 0, numPoints);
  glDisableClientState(GL_VERTEX_ARRAY);
  glDisableClientState(GL_COLOR_ARRAY);
  glLineWidth(1.0);
  
  // This is in world space
  glColor3f(0, 0, 0);
  const float velScale = 0.1f;
  glLineWidth(2.0);
  ci::gl::drawLine(m_agent->getPosition(), m_agent->getPosition() + m_agent->getVelocity() * velScale);
  glLineWidth(1.0);
  
  if(m_agent->hasDistanceSensor())
  {
    DistanceSensor* sensor = m_agent->getDistanceSensor();
    float sensedDistance = sensor->getDistance();
    glEnable(GL_LINE_STIPPLE);
    glLineStipple(2, 0xAAAA);
    glColor3f(0.2, 0.2, 0.2);    
    ci::gl::drawLine(sensor->getPosition(), sensor->getPosition() + sensor->getDirection() * sensedDistance);
    glDisable(GL_LINE_STIPPLE);
    
    glColor3f(1,0,0);
    if(sensedDistance < sensor->getMaxDistance())
    {
      drawPoint(ci::Vec3f(sensor->getCollision()), 5.0f);
    }
    
    // Sensor in local space
    glPushMatrix();
    glMultMatrixf(*m_pTM);
    glTranslatef(m_agent->getRadius(), 0, 0.001);
    float act = m_agent->getDistanceSensor()->getDistanceProportional();
    glColor3f(act,act,act);
    drawDisk(m_agent->getRadius() / 4.0, 0, 16, 2, GLU_FILL);
    glColor3f(0,0,0);
    drawDisk(m_agent->getRadius() / 4.0, 0, 16, 2, GLU_SILHOUETTE);
    glPopMatrix();
  }
  
  if(m_agent->hasGradientSensor())
  {
    GradientSensor* sensor = m_agent->getGradientSensor();
    float s = 1.0f - sensor->getActivation();
    
    // Sensor in local space
    glPushMatrix();
    glTranslatef(sensor->getPosition().x, sensor->getPosition().y, 0.0);
    glColor3f(s,s,s);
    drawDisk(m_agent->getRadius() / 4.0, 0, 16, 2, GLU_FILL);
    glColor3f(0,0,0);
    drawDisk(m_agent->getRadius() / 4.0, 0, 16, 2, GLU_SILHOUETTE);
    glPopMatrix();
  }
  
  if(m_agent->hasTorusSensor())
  {
    Sensor* sensor = m_agent->getTorusSensor();
    float s = 1.0f - sensor->getActivation();
    
    // Sensor in local space
    glPushMatrix();
    glTranslatef(sensor->getPosition().x, sensor->getPosition().y, 0.0);
    glColor3f(s,s,s);
    drawDisk(m_agent->getRadius() / 4.0, 0, 16, 2, GLU_FILL);
    glColor3f(0,0,0);
    drawDisk(m_agent->getRadius() / 4.0, 0, 16, 2, GLU_SILHOUETTE);
    glPopMatrix();
  }

  
  // draw positional range
  if(m_agent->positionWraps())
  {
    float p = m_agent->getMaxPosition();
    ci::gl::drawStrokedRect(ci::Rectf(ci::Vec2f(-p,-p), ci::Vec2f(p,p)));
  }

  // Change body color depending on energy level
  ci::Vec3f col = getColorMapRainbow(m_agent->getEnergy() / 5);
  ci::Vec4f col4 = ci::Vec4f(col);
  col4[3] = 0.5;
  m_agentDisk->m_color = col4;
  
  glPopAttrib();
  glEnable(GL_DEPTH_TEST);
}
Esempio n. 11
0
//----------------------------------------------------------------------------------------------------------------------
// CTRNNNeuronViz implementation
//----------------------------------------------------------------------------------------------------------------------
void CTRNNNeuronViz::update()
{
    glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT | GL_COLOR_BUFFER_BIT | GL_POLYGON_BIT);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_LIGHTING);
    glEnable(GL_BLEND);
    glDisable(GL_CULL_FACE);

    int N = m_ctrnn->getSize();

    // left upper corner of circle's bounding box at 0,0:
    const float segmentSize = TWO_PI / N;
    const float networkRadius = m_width / 2.5;
    const float neuronRadius = networkRadius / N;

    glPushMatrix();
    glMultMatrixf(*m_pTM);

    // connectivity
    if(m_renderConnections)
    {
        for(int i = 0; i < N; i++)
        {
            float angle = -((float)i + 0.5f) * segmentSize + PI_OVER_TWO;
            Vec3f midPoint (networkRadius * cosf(angle), networkRadius * sinf(angle), 0.0f);

            // draw only the selected neuron's connections
            if(i == m_selected || m_selected == -1)
            {
                // draw connections
                for(int j = 0; j < N; j++)
                {
                    const double eps = 0.001;
                    const float weight = m_ctrnn->getWeight(j,i);
                    if(fabs(weight) > eps)
                    {
                        float otherAngle = -((float)j + 0.5f) * segmentSize + PI_OVER_TWO;
                        Vec3f otherMidPoint (networkRadius * cosf(otherAngle), networkRadius * sinf(otherAngle), 0.0f);

                        glLineWidth(fabs(weight));
                        if(weight < 0)
                            glColor3f(235.0/255.0, 0.0/255.0, 103.0/255.0);
                        else
                            glColor3f(0,0,0);
                        ci::gl::drawLine(midPoint, otherMidPoint);
                    }
                }

                // render text
                if(m_renderText && i == m_selected)
                {
                    // box
                    glColor4f(0,0,0, 0.5f);
                    const float lineHeight = 13;
                    const float padding = 3;
                    const float textBoxH = 3 * lineHeight + 2 * padding;
                    ci::Vec2f textBoxPos = ci::Vec2f(&midPoint.x);
                    ci::gl::drawSolidRect(ci::Rectf(textBoxPos.x, textBoxPos.y, textBoxPos.x + m_width, textBoxPos.y + textBoxH));

                    // text
                    ci::Color textColor(1,1,1);
                    ci::Vec2f textPos = textBoxPos + ci::Vec2f(padding, padding);
                    char str [128];
                    sprintf(str, "Node: %i", i);
                    ci::gl::drawString(str, textPos, textColor, m_font);

                    sprintf(str, "b: %2.2f | t: %2.2f | g: %2.2f", m_ctrnn->getBias(i), m_ctrnn->getTimeConstant(i), m_ctrnn->getGain(i));
                    ci::gl::drawString(str, textPos + ci::Vec2f(0, lineHeight), textColor, m_font);

                    sprintf(str, "in: %1.3f | out: %1.3f", m_ctrnn->getExternalInput(i), m_ctrnn->getOutput(i));
                    ci::gl::drawString(str, textPos + ci::Vec2f(0, 2 * lineHeight), textColor, m_font);
                }
            }
        }
    }

    glLineWidth(1.0f);
    float outerRadius = neuronRadius + (neuronRadius * 0.5);
    for(int i = 0; i < N; i++)
    {
        ci::Color col = m_ctrnn->getState(i) > 0 ? ci::Color(0,0,0) : ci::Color(235.0/255.0, 0.0/255.0, 103.0/255.0);

        float angle = -((float)i + 0.5f) * segmentSize + PI_OVER_TWO;
        Vec3f midPoint (networkRadius * cosf(angle), networkRadius * sinf(angle), 0.0f);
        glPushMatrix();
        glTranslatef(midPoint);
        // white background
        glColor3f(1,1,1);
        drawDisk(outerRadius, 0.0, 32, 1);
        ci::gl::color(col);
        // disk size indicating output value
        drawDisk(neuronRadius * clamp(m_ctrnn->getOutput(i),0.0,1.0), 0.0, 32, 1);
        // ring size indicating external input value
        glColor3f(181.0/255.0, 206.0/255.0, 26.0/255.0);
        float width = radiansToDegrees(m_ctrnn->getExternalInput(i) * TWO_PI);
        dmx::drawPartialDisk(neuronRadius, outerRadius, 32, 1, 0, width, GLU_FILL);
        glColor3f(0,0,0);
        ci::gl::drawStrokedCircle(ci::Vec2f(0,0), outerRadius, 32);
        ci::gl::drawStrokedCircle(ci::Vec2f(0,0), neuronRadius, 32);
        glPopMatrix();
    }

    glPopMatrix();

    glPopAttrib();
}