[Kstars-devel] Drawing Geodesic Domes on the Sky

James Bowlin bowlin at mindspring.com
Tue May 30 22:13:53 CEST 2006


I accidently sent this directly to Jason so I am sending it again to the
list now.
 
On Tuesday 30 May 2006 07:29 am, you wrote:
> Can you send us a screenshot or two?

should I post them as attachments to this list or send them to you
directly?  

> How did you implement drawing the lines?  I guess you didn't add a 
> SkyComponent, but maybe just added the code directly in SkyMap::paintEvent()?

I tried to mimic SkyMap::drawConstellationLines() in skymapdraw.cpp.  Here is
the routine:

  void SkyMap::drawUserLines( QPainter& psky, double scale )
  {
    psky.setPen( QPen( QColor( data->colorScheme()->colorNamed( "HorzColor" ) ), 1, SolidLine ) ); 
    QPtrList<CSegment> userLines = data->getUserLineList();
    for (CSegment *cSeg = userLines.first(); cSeg; cSeg = userLines.next()) {
        SkyPoint *p1 = cSeg->firstNode();
        SkyPoint *p2 = cSeg->nextNode();
        QPoint o1 = getXY( p1, Options::useAltAz(), Options::useRefraction(), scale );
        QPoint o2 = getXY( p2, Options::useAltAz(), Options::useRefraction(), scale );
        psky.drawLine( o1.x(), o1.y(), o2.x(), o2.y());
    }   
  }

Then near the bottom of SkyMap::exportSkyImage() I added a call to it:

    drawHorizon( p, scale );
+   drawUserLines(p, scale);
    p.end();

I also added a call to it in SkyMap::paintEvent() as you figured out.  I put the routines
to add and erase userLines in kstarsdata.cpp:

  void KStarsData::addUserLine(double ra1, double dec1, double ra2, double dec2 ) {
    CSegment* cSeg = new CSegment();
    cSeg->addPoint(ra1, dec1);
    cSeg->addPoint(ra2, dec2);
    userLineList.append(cSeg);
  }
  void KStarsData::eraseUserLines( void ) {
    userLineList.clear();
  }
  QPtrList<CSegment> KStarsData::getUserLineList( void ) {
    return userLineList;
  }

I put glue code into kstarsdcop.cpp:

  void KStars::drawLine( double ra1, double dec1, double ra2, double dec2 ) {
        data()->addUserLine(ra1, dec1, ra2, dec2);
  }
  void KStars::eraseLines( void ) {
    data()->eraseUserLines();
  }

Then I spent about an hour compiling to get the headers right :-) :

$ grep -i -n userline *.h
kstarsdata.h:295:    QPtrList<CSegment> getUserLineList( void );
kstarsdata.h:297:    void addUserLine( double ra1, double dec1, double ra2, double dec2 );
kstarsdata.h:298:    void eraseUserLines( void );
kstarsdata.h:731:    QPtrList<CSegment> userLineList;
skymap.h:669:   void drawUserLines( QPainter& psky, double scale = 1.0 );

> I don't understand the segfaults you're getting; are you saying that HTM is 
> returning triangles that are far outside the region it should be returning?

Here is an example of running gdb on their lookup program:

Starting program: /data/jbowlin/Projects/HTM/perl/htm/lookup -corner 5 3 3
Depth = 5
(x,y,z)  =   0.9972609476841366,   0.0522642316338267,   0.0523359562429438
(ra,dec) =   2.9999999999999232,   3.0000000000000000
 Lookup performance: 0.000000 /sec
ID/Name  = 15887 N320033

Program received signal SIGSEGV, Segmentation fault.
0xb7fb9183 in SpatialIndex::nodeVertex (this=0x804d088, id=15887, v0=@0xbfbfe6a0, v1=@0xbfbfe6d0,
    v2=@0xbfbfe700) at SpatialIndex.cpp:147
147             v0 = vertices_[nodes_[idx].v_[0]];
gdb) print nodes_.size()
$2 = 10921

The problem is that the index is larger than the size of the nodes_[] array.
That funny size is 8 + 32 + 128 + 512 + 2048 + 8192 + 1
Which is the number of nodes in levels 0..5 + 1 for good measure.

The reason I pushed to quickly cobble together something that could plot geodesic
domes on the sky was so we could find problems like this that are not so obvious
when you're just returning a list of numbers (I guess a segfault is pretty obvious
though :).

I'm tracking the problem down and I think I have a work-around, although I would
like to actually fix the problem.  Since the number of nodes grows as 4^level you
can't store all the nodes in memory if the level is significant.  So they store
only the first buildlevel_ levels in memory and the rest they create temporarily
on the fly as needed.  The default buildlevel_ is 5 for levels 6 and higher.

The work-around is to change the line:

   htm = new htmInterface(depth);

to:

  if (depth < 6) {
      htm = new htmInterface(depth, depth - 1);
  else {
      htm = new htmInterface(depth);
  }

I figure they did not do extensive testing on meshes at the lower levels which is
why this bug slipped through.  I think we can get a bit of a performance boost if
our mesh is entirely in RAM but even if we can't fix the bug, the HTM is still a
big win for us.  I'm going to use the work-around for now.  I just now tried it
and only sane triangles are being created so it seems to be working.


> Please take your time, take as long a break as you need.  Don't get burned 
> out!  This is supposed to be fun, and besides, we need you :)

No worries.  I wouldn't tire myself if it wasn't fun.


-- 
Peace, James


More information about the Kstars-devel mailing list