[prev in list] [next in list] [prev in thread] [next in thread]
List: kstars-devel
Subject: Re: [Kstars-devel] Drawing comet tail patch
From: Charles <chp516 () gmail ! com>
Date: 2009-04-15 4:49:36
Message-ID: 89298fc00904142149r2327d392wba0c9044ba299129 () mail ! gmail ! com
[Download RAW message or body]
Hi all,
Sorry about the hasty submission last night, the patch was still
incorrect. I made a correction when the sun is in the second or the
third quadrant relative to the comet where the return value of the
atan function needs to be adjusted.
I find another defect with my patch: if the Sun is not on screen, the
map->toScreen((SkyPoint *) Sun) returns (-10000000, -10000000) which
makes the rotation incorrect. Can someone tell me whether there is a
more decent way to determine the location of the Sun?
Regards,
--
Charles
["comettail.patch" (application/octet-stream)]
Index: kstars/kstars/skycomponents/cometscomponent.cpp
===================================================================
--- kstars/kstars/skycomponents/cometscomponent.cpp (revision 954089)
+++ kstars/kstars/skycomponents/cometscomponent.cpp (working copy)
@@ -21,7 +21,10 @@
#include <QFile>
#include <QPen>
#include <QPainter>
+#include <QRadialGradient>
+#include <QPainterPath>
#include <kglobal.h>
+#include <cmath>
#include "Options.h"
#include "skyobjects/kscomet.h"
@@ -93,11 +96,17 @@
SkyMap *map = SkyMap::Instance();
+ // The following line is copied from skyobjects/ksmoon.cpp, they should be fix \
synchronously. + // TODO: Get rid of this ugly thing by making KSSun singleton.
+ KSSun *Sun = (KSSun*)KStarsData::Instance()->skyComposite()->findByName( "Sun" \
); +
+ // Fixme: If the Sun is not on screen, toScreen will return (-10000000.0, \
-10000000.0). + QPointF sp = map->toScreen( (SkyPoint *)Sun );
+
bool hideLabels = ! Options::showCometNames() || (map->isSlewing() && \
Options::hideLabels() ); double rsunLabelLimit = Options::maxRadCometName();
- psky.setPen( QPen( QColor( "darkcyan" ) ) );
- psky.setBrush( QBrush( QColor( "darkcyan" ) ) );
+ psky.setPen( Qt::NoPen );
foreach ( SkyObject *so, objectList() ) {
KSComet *com = (KSComet*)so;
@@ -109,18 +118,76 @@
if ( ! map->onScreen( o ) ) continue;
//if ( ( o.x() >= 0. && o.x() <= Width && o.y() >= 0. && o.y() <= Height ) )
+ float rot;
+ if ( abs( sp.x() - o.x() ) < 0.001 * abs( sp.y() - o.y() ) ) {
+ if ( sp.y() > o.y() )
+ rot = 90.0;
+ else
+ rot = -90.0;
+ } else {
+ float dy = sp.y() - o.y();
+ float dx = sp.x() - o.x();
+
+ rot = atan( dy / dx );
+ rot = rot * 180 / dms::PI;
+ if ( dx < 0 )
+ rot += 180;
+ }
+
float size = com->angSize() * map->scale() * dms::PI * \
Options::zoomFactor()/10800.0; + float radius = 0.5 * size;
+
+ psky.translate( o );
+ psky.rotate( rot );
+ psky.translate( QPointF( radius, 0 ) );
+
+ QRadialGradient gn( QPointF( -radius, 0 ),
+ radius,
+ QPointF( -radius, 0 ) );
+ gn.setColorAt( 0.0, QColor( "darkcyan" ) );
+ gn.setColorAt( 1.0, Qt::transparent );
+ psky.setBrush( gn );
+
if ( size < 1.0 ) {
- psky.drawPoint( o );
+ psky.drawPoint( QPointF( -radius, 0 ) );
} else {
- float x1 = o.x() - 0.5*size;
- float y1 = o.y() - 0.5*size;
+ float x1 = -size;
+ float y1 = -radius;
psky.drawEllipse( QRectF( x1, y1, size, size ) );
}
float tailsize = com->getTailAngSize().Degrees() * map->scale() * dms::PI * \
Options::zoomFactor()/10800.0;
+ QRadialGradient gt( QPointF( -radius, 0 ),
+ tailsize + radius,
+ QPointF( -radius, 0 ) );
+ gt.setColorAt( 0.0, QColor( "darkcyan" ) );
+ gt.setColorAt( 1.0, Qt::transparent );
+ psky.setBrush( gt );
+
+ // Using cubic bezier curve to draw the nucleus (the 2nd time) and the tail.
+ QPainterPath pt;
+ float len = tailsize + size;
+ float u; // an empirical scale factor
+ // If the comet is small, the shape doesn't matter much.
+ // Here u = 2 is to avoid a / radius resulting a NaN.
+ if ( radius < 0.1 )
+ u = 2;
+ else
+ u = sqrt( len / radius ); // empirical approximation
+ float v = sqrt( u / 2);
+ pt.moveTo( QPointF( -len, v * radius ) );
+ pt.cubicTo( QPointF( len / 3, u * radius ),
+ QPointF( len / 3, -u * radius ),
+ QPointF( -len, -v * radius ) );
+ pt.closeSubpath();
+ psky.drawPath( pt );
+
+ psky.translate( QPointF( -radius, 0 ) );
+ psky.rotate( -rot );
+ psky.translate( QPointF( -o.x(), -o.y() ) );
+
if ( hideLabels || com->rsun() >= rsunLabelLimit ) continue;
SkyLabeler::AddLabel( o, com, SkyLabeler::COMET_LABEL );
}
["screenshot.png" (image/png)]
_______________________________________________
Kstars-devel mailing list
Kstars-devel@kde.org
https://mail.kde.org/mailman/listinfo/kstars-devel
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic