[Marble-commits] KDE/kdeedu/marble/src/lib
Torsten Rahn
tackat at kde.org
Mon Jul 27 14:44:30 CEST 2009
SVN commit 1002971 by rahn:
- Add regionFromEllipse
- make variable names more consistent
M +89 -11 GeoPainter.cpp
M +19 -3 GeoPainter.h
--- trunk/KDE/kdeedu/marble/src/lib/GeoPainter.cpp #1002970:1002971
@@ -298,7 +298,7 @@
}
-void GeoPainter::drawEllipse ( const GeoDataCoordinates & centerPoint,
+void GeoPainter::drawEllipse ( const GeoDataCoordinates & centerPosition,
qreal width, qreal height,
bool isGeoProjected )
{
@@ -308,7 +308,7 @@
AbstractProjection *projection = d->m_viewport->currentProjection();
if ( !isGeoProjected ) {
- bool visible = projection->screenCoordinates( centerPoint, d->m_viewport, d->m_x, y, pointRepeatNum, QSizeF( width, height ), globeHidesPoint );
+ bool visible = projection->screenCoordinates( centerPosition, d->m_viewport, d->m_x, y, pointRepeatNum, QSizeF( width, height ), globeHidesPoint );
if ( visible ) {
// Draw all the x-repeat-instances of the point on the screen
@@ -322,9 +322,9 @@
// Initialize variables
qreal centerLon = 0.0;
qreal centerLat = 0.0;
- qreal altitude = centerPoint.altitude();
- centerPoint.geoCoordinates( centerLon, centerLat,
- GeoDataCoordinates::Degree );
+ qreal altitude = centerPosition.altitude();
+ centerPosition.geoCoordinates( centerLon, centerLat,
+ GeoDataCoordinates::Degree );
// Ensure a valid latitude range:
if ( centerLat + 0.5 * height > 90.0 || centerLat - 0.5 * height < -90.0 ) {
@@ -371,7 +371,85 @@
}
-void GeoPainter::drawImage ( const GeoDataCoordinates & centerPoint,
+QRegion GeoPainter::regionFromEllipse ( const GeoDataCoordinates & centerPosition,
+ qreal width, qreal height,
+ bool isGeoProjected,
+ qreal strokeWidth )
+{
+ int pointRepeatNum;
+ qreal y;
+ bool globeHidesPoint;
+ AbstractProjection *projection = d->m_viewport->currentProjection();
+
+ if ( !isGeoProjected ) {
+ QRegion regions;
+
+ bool visible = projection->screenCoordinates( centerPosition, d->m_viewport, d->m_x, y, pointRepeatNum, QSizeF( width, height ), globeHidesPoint );
+
+ if ( visible ) {
+ // Draw all the x-repeat-instances of the point on the screen
+ for( int it = 0; it < pointRepeatNum; ++it ) {
+ regions += QRegion( d->m_x[it] - width / 2.0,
+ y - height / 2.0,
+ width + strokeWidth,
+ height + strokeWidth,
+ QRegion::Ellipse );
+ }
+ }
+ return regions;
+ }
+ else {
+ // Initialize variables
+ qreal centerLon = 0.0;
+ qreal centerLat = 0.0;
+ qreal altitude = centerPosition.altitude();
+ centerPosition.geoCoordinates( centerLon, centerLat,
+ GeoDataCoordinates::Degree );
+
+ // Ensure a valid latitude range:
+ if ( centerLat + 0.5 * height > 90.0 || centerLat - 0.5 * height < -90.0 ) {
+ return QRegion();
+ }
+
+ // Don't show the ellipse if it's too small:
+ GeoDataLatLonBox ellipseBox( centerLat + 0.5 * height, centerLat - 0.5 * height,
+ centerLon + 0.5 * width, centerLon - 0.5 * width,
+ GeoDataCoordinates::Degree );
+ if ( !d->m_viewport->viewLatLonAltBox().intersects( ellipseBox ) ||
+ !d->m_viewport->resolves( ellipseBox ) ) return QRegion();
+
+ GeoDataLinearRing ellipse;
+ qreal lon = 0.0;
+ qreal lat = 0.0;
+
+ // Optimizing the precision by determining the size which the
+ // ellipse covers on the screen:
+ qreal degreeResolution = d->m_viewport->angularResolution() * RAD2DEG;
+ // To create a circle shape even for very small precision we require uneven numbers:
+ int precision = width / degreeResolution / 8 + 1;
+ if ( precision > 81 ) precision = 81;
+
+ // Calculate the shape of the upper half of the ellipse:
+ for ( int i = 0; i <= precision; ++i ) {
+ qreal t = 1.0 - 2.0 * (qreal)(i) / (qreal)(precision);
+ lat = centerLat + 0.5 * height * sqrt( 1.0 - t * t );
+ lon = centerLon + 0.5 * width * t;
+ ellipse << GeoDataCoordinates( lon, lat, altitude, GeoDataCoordinates::Degree );
+ }
+ // Calculate the shape of the lower half of the ellipse:
+ for ( int i = 0; i <= precision; ++i ) {
+ qreal t = 2.0 * (qreal)(i) / (qreal)(precision) - 1.0;
+ lat = centerLat - 0.5 * height * sqrt( 1.0 - t * t );
+ lon = centerLon + 0.5 * width * t;
+ ellipse << GeoDataCoordinates( lon, lat, altitude, GeoDataCoordinates::Degree );
+ }
+
+ return regionFromPolygon( ellipse, Qt::OddEvenFill, strokeWidth );
+ }
+}
+
+
+void GeoPainter::drawImage ( const GeoDataCoordinates & centerPosition,
const QImage & image /*, bool isGeoProjected */ )
{
// isGeoProjected = true would project the image/pixmap onto the globe. This
@@ -384,7 +462,7 @@
AbstractProjection *projection = d->m_viewport->currentProjection();
// if ( !isGeoProjected ) {
- bool visible = projection->screenCoordinates( centerPoint, d->m_viewport, d->m_x, y, pointRepeatNum, image.size(), globeHidesPoint );
+ bool visible = projection->screenCoordinates( centerPosition, d->m_viewport, d->m_x, y, pointRepeatNum, image.size(), globeHidesPoint );
if ( visible ) {
// Draw all the x-repeat-instances of the point on the screen
@@ -396,7 +474,7 @@
}
-void GeoPainter::drawPixmap ( const GeoDataCoordinates & centerPoint,
+void GeoPainter::drawPixmap ( const GeoDataCoordinates & centerPosition,
const QPixmap & pixmap /* , bool isGeoProjected */ )
{
int pointRepeatNum;
@@ -406,7 +484,7 @@
// if ( !isGeoProjected ) {
// FIXME: Better visibility detection that takes the circle geometry into account
- bool visible = projection->screenCoordinates( centerPoint, d->m_viewport, d->m_x, y, pointRepeatNum, pixmap.size(), globeHidesPoint );
+ bool visible = projection->screenCoordinates( centerPosition, d->m_viewport, d->m_x, y, pointRepeatNum, pixmap.size(), globeHidesPoint );
if ( visible ) {
// Draw all the x-repeat-instances of the point on the screen
@@ -797,7 +875,7 @@
}
-void GeoPainter::drawRoundRect ( const GeoDataCoordinates ¢erPoint,
+void GeoPainter::drawRoundRect ( const GeoDataCoordinates ¢erPosition,
int width, int height,
int xRnd, int yRnd,
bool isGeoProjected )
@@ -809,7 +887,7 @@
if ( !isGeoProjected ) {
// FIXME: Better visibility detection that takes the circle geometry into account
- bool visible = projection->screenCoordinates( centerPoint, d->m_viewport, d->m_x, y, pointRepeatNum, QSizeF( width, height ), globeHidesPoint );
+ bool visible = projection->screenCoordinates( centerPosition, d->m_viewport, d->m_x, y, pointRepeatNum, QSizeF( width, height ), globeHidesPoint );
if ( visible ) {
// Draw all the x-repeat-instances of the point on the screen
--- trunk/KDE/kdeedu/marble/src/lib/GeoPainter.h #1002970:1002971
@@ -256,6 +256,22 @@
/*!
+ \brief Creates a region for an ellipse at a given position
+
+ A QRegion object is created that represents the area covered by
+ GeoPainter::drawEllipse(). As such it can be used e.g. for input event
+ handling for objects that have been painted using GeoPainter::drawEllipse().
+
+ The \a strokeWidth allows to extrude the QRegion by half the amount of
+ "stroke width" pixels. For input event handling it's always advisable to use
+ a width that is slightly bigger than the width of the painter's pen.
+*/
+ QRegion regionFromEllipse ( const GeoDataCoordinates & centerPosition,
+ qreal width, qreal height, bool isGeoProjected = false,
+ qreal strokeWidth = 3 );
+
+
+/*!
\brief Draws an image at the given position.
The image is placed with its center located at the given \a centerPosition.
@@ -399,7 +415,7 @@
in screen coordinates. In this case the \a width and the \a height
are interpreted to be pixels.
*/
- void drawRect ( const GeoDataCoordinates & centerPoint,
+ void drawRect ( const GeoDataCoordinates & centerPosition,
qreal width, qreal height,
bool isGeoProjected = false );
@@ -419,7 +435,7 @@
a width that is slightly bigger than the width of the painter's pen. This is
especially true for small objects.
*/
- QRegion regionFromRect ( const GeoDataCoordinates & centerPoint,
+ QRegion regionFromRect ( const GeoDataCoordinates & centerPosition,
qreal width, qreal height,
bool isGeoProjected = false,
qreal strokeWidth = 3 );
@@ -447,7 +463,7 @@
in screen coordinates. In this case the \a width and the \a height
are interpreted to be pixels.
*/
- void drawRoundRect ( const GeoDataCoordinates & centerPoint,
+ void drawRoundRect ( const GeoDataCoordinates & centerPosition,
int width, int height,
int xRnd = 25, int yRnd = 25,
bool isGeoProjected = false );
More information about the Marble-commits
mailing list