Ejemplo n.º 1
0
// Draw a "spiral" arc defined by circle arcs around a center, a start and an end radius
void spiralArcTo( QPainterPath& path, const QPointF& center, qreal startAngle, qreal startRadius, qreal endAngle, qreal endRadius, int direction )
{
  // start point
  QPointF A = circlePoint( center, startRadius, startAngle );
  // end point
  QPointF B = circlePoint( center, endRadius, endAngle );
  // middle points
  qreal deltaAngle;

  deltaAngle = endAngle - startAngle;
  if ( direction * deltaAngle < 0.0 )
    deltaAngle = deltaAngle + direction * 2 * M_PI;

  QPointF I1 = circlePoint( center, 0.75 * startRadius + 0.25 * endRadius, startAngle + 0.25 * deltaAngle );
  QPointF I2 = circlePoint( center, 0.50 * startRadius + 0.50 * endRadius, startAngle + 0.50 * deltaAngle );
  QPointF I3 = circlePoint( center, 0.25 * startRadius + 0.75 * endRadius, startAngle + 0.75 * deltaAngle );

  qreal cRadius;
  QPointF cCenter;
  // first circle arc
  if ( ! pointsToCircle( A, I1, I2, cCenter, cRadius ) )
  {
    // aligned points => draw a straight line
    path.lineTo( I2 );
  }
  else
  {
    // angles in the new circle
    qreal a1 = atan2( cCenter.y() - A.y(), A.x() - cCenter.x() );
    qreal a2 = atan2( cCenter.y() - I2.y(), I2.x() - cCenter.x() );
    pathArcTo( path, cCenter, cRadius, a1, a2, direction );
  }

  // second circle arc
  if ( ! pointsToCircle( I2, I3, B, cCenter, cRadius ) )
  {
    // aligned points => draw a straight line
    path.lineTo( B );
  }
  else
  {
    // angles in the new circle
    qreal a1 = atan2( cCenter.y() - I2.y(), I2.x() - cCenter.x() );
    qreal a2 = atan2( cCenter.y() - B.y(), B.x() - cCenter.x() );
    pathArcTo( path, cCenter, cRadius, a1, a2, direction );
  }
}
Ejemplo n.º 2
0
/**
 * Updates the preview points (if necessary)
 *
 */
void EFX::updatePreview()
{
	if (m_previewPointArray == NULL)
		return;

	int stepCount = 128;
	int step = 0;
	float stepSize = (float)(1) / ((float)(stepCount) / (M_PI * 2.0));

	float i = 0;
	float *x = new float;
	float *y = new float;

	/* Resize the array to contain stepCount points */
	m_previewPointArray->resize(stepCount);

	if (m_algorithm == KCircleAlgorithmName)
	{
		/* Draw a preview of a circle */
		for (i = 0; i < (M_PI * 2.0); i += stepSize)
		{
			circlePoint(this, i, x, y);
			m_previewPointArray->setPoint(step++,
						      static_cast<int> (*x),
						      static_cast<int> (*y));
		}
	}
	else if (m_algorithm == KEightAlgorithmName)
	{
		/* Draw a preview of a eight */
		for (i = 0; i < (M_PI * 2.0); i += stepSize)
		{
			eightPoint(this, i, x, y);
			m_previewPointArray->setPoint(step++,
						      static_cast<int> (*x),
						      static_cast<int> (*y));
		}
	}
	else if (m_algorithm == KLineAlgorithmName)
	{
		/* Draw a preview of a line */
		for (i = 0; i < (M_PI * 2.0); i += stepSize)
		{
			linePoint(this, i, x, y);
			m_previewPointArray->setPoint(step++,
						      static_cast<int> (*x),
						      static_cast<int> (*y));
		}
	}
	else if (m_algorithm == KDiamondAlgorithmName)
	{
		/* Draw a preview of a diamond */
		for (i = 0; i < (M_PI * 2.0); i += stepSize)
		{
			diamondPoint(this, i, x, y);
			m_previewPointArray->setPoint(step++,
						      static_cast<int> (*x),
						      static_cast<int> (*y));
		}
	}
	else if (m_algorithm == KTriangleAlgorithmName)
	{
		/* Draw a preview of a triangle */
		for (i = 0; i < (M_PI * 2.0); i += stepSize)
		{
			trianglePoint(this, i, x, y);
			m_previewPointArray->setPoint(step++,
						      static_cast<int> (*x),
						      static_cast<int> (*y));
		}
	}
	else if (m_algorithm == KLissajousAlgorithmName)
	{
		/* Draw a preview of a lissajous */
		for (i = 0; i < (M_PI * 2.0); i += stepSize)
		{
			lissajousPoint(this, i, x, y);
			m_previewPointArray->setPoint(step++,
						      static_cast<int> (*x),
						      static_cast<int> (*y));
		}
	}
	else
	{
		m_previewPointArray->resize(0);
	}

	delete x;
	delete y;
}
Ejemplo n.º 3
0
QPolygonF curvedArrow( QPointF po, QPointF pm, QPointF pd, qreal startWidth, qreal width, qreal headSize, QgsArrowSymbolLayer::HeadType headType, qreal offset )
{
  qreal circleRadius;
  QPointF circleCenter;
  if ( ! pointsToCircle( po, pm, pd, circleCenter, circleRadius ) || circleRadius > 10000.0 )
  {
    // aligned points => draw a straight arrow
    return straightArrow( po, pd, startWidth, width, headSize, headType, offset );
  }

  // angles of each point
  qreal angle_o = clampAngle( atan2( circleCenter.y() - po.y(), po.x() - circleCenter.x() ) );
  qreal angle_m = clampAngle( atan2( circleCenter.y() - pm.y(), pm.x() - circleCenter.x() ) );
  qreal angle_d = clampAngle( atan2( circleCenter.y() - pd.y(), pd.x() - circleCenter.x() ) );

  // arc direction : 1 = counter-clockwise, -1 = clockwise
  int direction = clampAngle( angle_m - angle_o ) < clampAngle( angle_m - angle_d ) ? 1 : -1;

  qreal deltaAngle = angle_d - angle_o;
  if ( direction * deltaAngle < 0.0 )
    deltaAngle = deltaAngle + direction * 2 * M_PI;

  qreal length = euclidian_distance( po, pd );
  // for close points and deltaAngle < 180, draw a straight line
  if ( fabs( deltaAngle ) < M_PI && ((( headType == QgsArrowSymbolLayer::HeadSingle ) && ( length < headSize ) ) ||
                                     (( headType == QgsArrowSymbolLayer::HeadReversed ) && ( length < headSize ) ) ||
                                     (( headType == QgsArrowSymbolLayer::HeadDouble ) && ( length < 2*headSize ) ) ) )
  {
    return straightArrow( po, pd, startWidth, width, headSize, headType, offset );
  }

  // ajust coordinates to include offset
  circleRadius += offset;
  po = circlePoint( circleCenter, circleRadius, angle_o );
  pm = circlePoint( circleCenter, circleRadius, angle_m );
  pd = circlePoint( circleCenter, circleRadius, angle_d );

  qreal headAngle = direction * atan( headSize / circleRadius );

  QPainterPath path;

  if ( headType == QgsArrowSymbolLayer::HeadDouble )
  {
    // the first head
    path.moveTo( po );
    path.lineTo( circlePoint( circleCenter, circleRadius + direction * headSize, angle_o + headAngle ) );

    pathArcTo( path, circleCenter, circleRadius + direction * width / 2, angle_o + headAngle, angle_d - headAngle, direction );

    // the second head
    path.lineTo( circlePoint( circleCenter, circleRadius + direction * headSize, angle_d - headAngle ) );
    path.lineTo( pd );
    path.lineTo( circlePoint( circleCenter, circleRadius - direction * headSize, angle_d - headAngle ) );

    pathArcTo( path, circleCenter, circleRadius - direction * width / 2, angle_d - headAngle, angle_o + headAngle, -direction );

    // the end of the first head
    path.lineTo( circlePoint( circleCenter, circleRadius - direction * headSize, angle_o + headAngle ) );
    path.lineTo( po );
  }
  else if ( headType == QgsArrowSymbolLayer::HeadSingle )
  {
    path.moveTo( circlePoint( circleCenter, circleRadius + direction * startWidth / 2, angle_o ) );

    spiralArcTo( path, circleCenter, angle_o, circleRadius + direction * startWidth / 2, angle_d - headAngle, circleRadius + direction * width / 2, direction );

    // the arrow head
    path.lineTo( circlePoint( circleCenter, circleRadius + direction * headSize, angle_d - headAngle ) );
    path.lineTo( pd );
    path.lineTo( circlePoint( circleCenter, circleRadius - direction * headSize, angle_d - headAngle ) );

    spiralArcTo( path, circleCenter, angle_d - headAngle, circleRadius - direction * width / 2, angle_o, circleRadius - direction * startWidth / 2, -direction );

    path.lineTo( circlePoint( circleCenter, circleRadius + direction * startWidth / 2, angle_o ) );
  }
  else if ( headType == QgsArrowSymbolLayer::HeadReversed )
  {
    path.moveTo( circlePoint( circleCenter, circleRadius + direction * width / 2, angle_o + headAngle ) );

    spiralArcTo( path, circleCenter, angle_o + headAngle, circleRadius + direction * width / 2, angle_d, circleRadius + direction * startWidth / 2, direction );

    path.lineTo( circlePoint( circleCenter, circleRadius - direction * startWidth / 2, angle_d ) );

    spiralArcTo( path, circleCenter, angle_d, circleRadius - direction * startWidth / 2, angle_o + headAngle, circleRadius - direction * width / 2, - direction );

    path.lineTo( circlePoint( circleCenter, circleRadius - direction * headSize, angle_o + headAngle ) );
    path.lineTo( po );
    path.lineTo( circlePoint( circleCenter, circleRadius + direction * headSize, angle_o + headAngle ) );
    path.lineTo( circlePoint( circleCenter, circleRadius + direction * width / 2, angle_o + headAngle ) );
  }

  return path.toSubpathPolygons().at( 0 );
}
Ejemplo n.º 4
0
bool EFX::preview(QVector <QPoint>& polygon)
{
	bool retval = true;
	int stepCount = 128;
	int step = 0;
	qreal stepSize = (qreal)(1) / ((qreal)(stepCount) / (M_PI * 2.0));

	qreal i = 0;
	qreal x = 0;
	qreal y = 0;

	/* Resize the array to contain stepCount points */
	polygon.resize(stepCount);

	/* Since algorithm is identified by a string, we don't want to do N
	   string comparisons on each for loop increment. So, it's a bit faster
	   to check the algorithm only once and then do the looping. */
	if (m_algorithm == KCircleAlgorithmName)
	{
		/* Draw a preview of a circle */
		for (step = 0; step < stepCount; step++)
		{
			circlePoint(this, i, &x, &y);
			polygon[step] = QPoint(int(x), int(y));
			i += stepSize;
		}
	}
	else if (m_algorithm == KEightAlgorithmName)
	{
		/* Draw a preview of a eight */
		for (step = 0; step < stepCount; step++)
		{
			eightPoint(this, i, &x, &y);
			polygon[step] = QPoint(int(x), int(y));
			i += stepSize;
		}
	}
	else if (m_algorithm == KLineAlgorithmName)
	{
		/* Draw a preview of a line */
		for (step = 0; step < stepCount; step++)
		{
			linePoint(this, i, &x, &y);
			polygon[step] = QPoint(int(x), int(y));
			i += stepSize;
		}
	}
	else if (m_algorithm == KDiamondAlgorithmName)
	{
		/* Draw a preview of a diamond */
		for (step = 0; step < stepCount; step++)
		{
			diamondPoint(this, i, &x, &y);
			polygon[step] = QPoint(int(x), int(y));
			i += stepSize;
		}
	}
	else if (m_algorithm == KTriangleAlgorithmName)
	{
		/* Draw a preview of a triangle */
		for (step = 0; step < stepCount; step++)
		{
			trianglePoint(this, i, &x, &y);
			polygon[step] = QPoint(int(x), int(y));
			i += stepSize;
		}
	}
	else if (m_algorithm == KLissajousAlgorithmName)
	{
		/* Draw a preview of a lissajous */
		for (step = 0; step < stepCount; step++)
		{
			lissajousPoint(this, i, &x, &y);
			polygon[step] = QPoint(int(x), int(y));
			i += stepSize;
		}
	}
	else
	{
		polygon.resize(0);
		retval = false;
	}

	return retval;
}