Example #1
0
QPolygonF straightArrow( QPointF po, QPointF pd, qreal startWidth, qreal width, qreal headSize, QgsArrowSymbolLayer::HeadType headType, qreal offset )
{
  QPolygonF polygon; // implicitly shared
  // vector length
  qreal length = euclidian_distance( po, pd );

  // shift points if there is not enough room for the head(s)
  if (( headType == QgsArrowSymbolLayer::HeadSingle ) && ( length < headSize ) )
  {
    po = pd - ( pd - po ) / length * headSize;
    length = headSize;
  }
  else if (( headType == QgsArrowSymbolLayer::HeadReversed ) && ( length < headSize ) )
  {
    pd = po + ( pd - po ) / length * headSize;
    length = headSize;
  }
  else if (( headType == QgsArrowSymbolLayer::HeadDouble ) && ( length < 2 * headSize ) )
  {
    QPointF v = ( pd - po ) / length * headSize;
    QPointF npo = ( po + pd ) / 2.0 - v;
    QPointF npd = ( po + pd ) / 2.0 + v;
    po = npo;
    pd = npd;
    length = 2 * headSize;
  }

  qreal bodyLength = length - headSize;

  // unit vector
  QPointF unitVec = ( pd - po ) / length;
  // perpendicular vector
  QPointF perpVec( -unitVec.y(), unitVec.x() );

  // set offset
  po += perpVec * offset;
  pd += perpVec * offset;

  if ( headType == QgsArrowSymbolLayer::HeadDouble )
  {
    // first head
    polygon << po;
    polygon << po + unitVec * headSize + perpVec * headSize;
    polygon << po + unitVec * headSize + perpVec * ( width * 0.5 );

    polygon << po + unitVec * bodyLength + perpVec * ( width * 0.5 );

    // second head
    polygon << po + unitVec * bodyLength + perpVec * headSize;
    polygon << pd;
    polygon << po + unitVec * bodyLength - perpVec * headSize;

    polygon << po + unitVec * bodyLength - perpVec * ( width * 0.5 );

    // end of the first head
    polygon << po + unitVec * headSize - perpVec * ( width * 0.5 );
    polygon << po + unitVec * headSize - perpVec * headSize;
  }
  else if ( headType == QgsArrowSymbolLayer::HeadSingle )
  {
    polygon << po - perpVec * ( startWidth * 0.5 );
    polygon << po + perpVec * ( startWidth * 0.5 );
    polygon << po + unitVec * bodyLength + perpVec * ( width * 0.5 );
    polygon << po + unitVec * bodyLength + perpVec * headSize;
    polygon << pd;
    polygon << po + unitVec * bodyLength - perpVec * headSize;
    polygon << po + unitVec * bodyLength - perpVec * ( width * 0.5 );
  }
  else if ( headType == QgsArrowSymbolLayer::HeadReversed )
  {
    // first head
    polygon << po;
    polygon << po + unitVec * headSize + perpVec * headSize;
    polygon << po + unitVec * headSize + perpVec * ( width * 0.5 );

    polygon << pd + perpVec * ( startWidth * 0.5 );
    polygon << pd - perpVec * ( startWidth * 0.5 );

    polygon << po + unitVec * headSize - perpVec * ( width * 0.5 );
    polygon << po + unitVec * headSize - perpVec * headSize;
  }
  // close the polygon
  polygon << polygon.first();

  return polygon;
}
Example #2
0
void BGNode::drawFace(ofShader & mEyeShader) {

/*
    int n = neighbours.size();
    ofVec2f toVector(1,0);
    if(n > 0)
        toVector = (neighbours[0]->position - position).normalize();


    ofVec2f perpVec(-toVector.y, toVector.x);
*/

    ofSetColor(255);

    float offset = .05 * nodeRadius;
    float perpOffset = .6 * nodeRadius;
    float eyeRadius = .6 * nodeRadius;

    ofVec2f toVector = mSurfaceNormal;
    ofVec2f perpVec(-toVector.y, toVector.x);

    ofVec2f goalPos = position;
    if(neighbours.size() > 0)
        goalPos = neighbours[0]->position;

    float texFactor = .6 * nodeRadius;

    for(int i=0; i<2; ++i) {

        int factor = i == 0 ? 1 : -1;
        ofVec2f pos = position + toVector * offset + factor * perpVec * perpOffset;

        ofMesh eyeMesh;
        eyeMesh.setMode(OF_PRIMITIVE_TRIANGLE_STRIP);

        for(int j=0; j<4; ++j) {

            ofVec2f texPos(j % 2, j / 2);

            ofVec2f vPos = pos + (texPos.x - .5) * texFactor * perpVec + (texPos.y - .5) * texFactor * toVector;

            eyeMesh.addVertex(ofVec3f(vPos.x, vPos.y, 0));
            eyeMesh.addTexCoord(texPos);
        }

        ofVec2f goalPos = position;
        if(neighbours.size() > 0)
            goalPos = neighbours[0]->position;

        ofVec2f toGoal = goalPos - pos;
        float toGoalLength = toGoal.length();
        ofVec2f pupilPos = pos;
        if(toGoalLength > 0.01)
            pupilPos = pos + .25 * eyeRadius / toGoalLength * toGoal;

        mEyeShader.begin();
        mEyeShader.setUniform2f("uCenter", pos.x, pos.y);
        mEyeShader.setUniform2f("uFocusPoint", goalPos.x, goalPos.y);
        mEyeShader.setUniform2f("uPupilLoc", pupilPos.x, pupilPos.y);
        mEyeShader.setUniform1i("uFlipHorizontally", i > 0);
        
        eyeMesh.draw();
        mEyeShader.end();
    }

    ofMesh mouthMesh;
    mouthMesh.setMode(OF_PRIMITIVE_TRIANGLE_STRIP);

    for(int i=0; i<21; ++i) {
        float t = i / 20.0;
        float x = .6 * (t - .5) * nodeRadius;
        float yVar = 2 * abs(t - .5);
        float y = (-yVar * yVar * (1 - yVar) * .6 - .3) * nodeRadius;

        for(int it=0; it<2; ++it) {
            mouthMesh.addVertex(position + y * toVector + x * perpVec);
            mouthMesh.addColor(ofColor(0));
            y -= 3;
        }

    }

    mouthMesh.draw();
}