make annotations big enough to show up
authorDiane Trout <diane@caltech.edu>
Wed, 29 Mar 2006 08:24:11 +0000 (08:24 +0000)
committerDiane Trout <diane@caltech.edu>
Wed, 29 Mar 2006 08:24:11 +0000 (08:24 +0000)
fixes ticket:69 (or at least improves it)
Annotations could disapper if the width of the annotation was less than
one pixel. This patch forces it to be at least one pixel. However
it appears that the scrollbar is moving things in non-integral pixel sizes
so the annotations end up flashing as they render over different fractions
of two pixels.

alg/glsequence.cpp
alg/glsequence.hpp
alg/test/test_glsequence.cpp

index e38da9d417e40999d0e20df04996c61cc7456094..893e6fcfc8ace6df612a32581066baafcf617a24 100644 (file)
@@ -149,21 +149,33 @@ Color GlSequence::color()
 }
 
 
-int GlSequence::get_viewport_pixel_width()
+int GlSequence::get_viewport_width_in_pixels()
 {
   GLint viewport[4];
   glGetIntegerv(GL_VIEWPORT, viewport);
   return viewport[3]; // grab the viewport width
 }
 
+GLfloat GlSequence::get_pixel_width(GLfloat left, GLfloat right) const
+{
+  return get_pixel_width(left, right, get_viewport_width_in_pixels());
+}
+
+GLfloat
+GlSequence::get_pixel_width(GLfloat left, GLfloat right, int vp_width) const
+{
+  return round((right-left)/vp_width);
+}
+
+bool GlSequence::is_sequence_renderable(GLfloat left, GLfloat right) const
+{
+  return is_sequence_renderable(left, right, get_viewport_width_in_pixels());
+}
+
 bool GlSequence::is_sequence_renderable(GLfloat left, 
                                         GLfloat right, 
                                         int viewport_width) const
 {
-  // if called with default argument, go get the viewable width
-  if (viewport_width == -1) {
-    viewport_width = get_viewport_pixel_width();
-  }
   GLfloat world_width = right - left;
   GLfloat pixels_needed = (char_pix_per_world_unit * world_width);
 
@@ -184,13 +196,19 @@ void GlSequence::draw(GLfloat left, GLfloat right) const
   draw_annotations(left, right);
 }
 
-void GlSequence::draw_box(GLfloat left, GLfloat right, 
+void GlSequence::draw_box(GLfloat world_left, GLfloat world_right,
+                          GLfloat left, GLfloat right, 
                           GLfloat height, GLfloat z) const
 {
+  GLfloat pixel_width = get_pixel_width(world_left, world_right);
   GLfloat offset = height/2.0;
   GLfloat top = seq_y + offset;
   GLfloat bottom = seq_y - offset;
-    
+  
+  // make our box be at least 1 pixel
+  if ((right-left) < pixel_width) {
+    right = left + pixel_width;
+  }
   glBegin(GL_QUADS);
     glVertex3f(left,  top,    z);
     glVertex3f(left,  bottom, z);
@@ -199,34 +217,34 @@ void GlSequence::draw_box(GLfloat left, GLfloat right,
   glEnd();
 }
 
-void GlSequence::draw_track(GLfloat , GLfloat ) const
+void GlSequence::draw_track(GLfloat left, GLfloat right) const
 {
   glColor3fv(drawColor.get());
   // draw main sequence track
-  draw_box(seq_x, seq_x+seq.size(), seq_height, 0.0);
+  draw_box(left, right, seq_x, seq_x+seq.size(), seq_height, 0.0);
 }
 
-void GlSequence::draw_annotations(GLfloat , GLfloat ) const
+void GlSequence::draw_annotations(GLfloat left, GLfloat right) const
 {
   // draw annotations
-  GLfloat annotation_z = seq_z + 1.0;
+  GLfloat annotation_z = seq_z + 10.0;
   const std::list<annot>& annots = seq.annotations();
   const std::list<motif>& motifs = seq.motifs();
   for (std::list<annot>::const_iterator annot_itor = annots.begin();
        annot_itor != annots.end();
-       ++annot_itor, ++annotation_z)
+       ++annot_itor)
   {
-    glColor3f(0.0, 0.5, 0.0);
-    draw_box(seq_x+annot_itor->start, seq_x+annot_itor->end, 
+    glColor3f(0.0, 0.8, 0.0);
+    draw_box(left, right, seq_x+annot_itor->start, seq_x+annot_itor->end, 
              seq_height, annotation_z);
   }
   // if motifs?
   for (std::list<motif>::const_iterator motifs_itor = motifs.begin();
        motifs_itor != motifs.end();
-       ++motifs_itor, ++annotation_z)
+       ++motifs_itor)
   {
     glColor3fv(color_mapper.lookup("motif", motifs_itor->sequence).get());
-    draw_box(seq_x+motifs_itor->start, seq_x+motifs_itor->end, 
+    draw_box(left, right, seq_x+motifs_itor->start, seq_x+motifs_itor->end, 
              seq_height, annotation_z);
   }
 
index 0133230b9c5038470498d2d3306e2ef69ccdabf9..b9a84f91ada055933b33aabdee803f12bf74c735 100644 (file)
@@ -57,6 +57,13 @@ public:
   void setColor(Color &);
   Color color();
 
+  //! how big is a pixel in world coordinats
+  GLfloat get_pixel_width(GLfloat, GLfloat) const;
+  //! how big is a pixel in world coordinats (specifying viewport size)
+  GLfloat get_pixel_width(GLfloat, GLfloat, int) const;
+
+  //! are we close enough that it would make sense to view the base pairs?
+  bool is_sequence_renderable(GLfloat left, GLfloat right) const;
   //! are we close enough that it would make sense to view the base pairs?
   /*! though we don't actually check to see if there's sequence in our
    *  view, just that there's enough pixels to render something if 
@@ -66,9 +73,7 @@ public:
    *             coordinates
    *  \param[in] pixel_width allow setting the current viewport pixel width
    */
-  bool is_sequence_renderable(GLfloat left, 
-                              GLfloat right, 
-                              int pixel_width=-1) const;
+  bool is_sequence_renderable(GLfloat, GLfloat, int) const;
 
   friend bool operator==(const GlSequence &left, const GlSequence &right);
 
@@ -83,9 +88,9 @@ protected:
   const GLfloat char_pix_per_world_unit;
 
   //! Return the pixel width of the opengl viewport.
-  static int get_viewport_pixel_width();
+  static int get_viewport_width_in_pixels();
   //! draw a from left to right +/- height/2
-  void draw_box(GLfloat left, GLfloat right, GLfloat height, GLfloat z) const;
+  void draw_box(GLfloat world_left, GLfloat world_right, GLfloat left, GLfloat right, GLfloat height, GLfloat z) const;
   //! draw sequence as a bar
   void draw_track(GLfloat, GLfloat) const;
   void draw_annotations(GLfloat, GLfloat) const;
index 9c7853043f38ff33d70614a776ac47ea952e8eff..bb0cb49194eb2160bb9409d88cfdb31490bcbd70 100644 (file)
@@ -1,4 +1,5 @@
 #include <boost/test/auto_unit_test.hpp>
+#include <boost/test/floating_point_comparison.hpp>
 
 #include <string>
 
@@ -53,6 +54,9 @@ BOOST_AUTO_TEST_CASE( glsequence_renderable )
   BOOST_CHECK_EQUAL(s.is_sequence_renderable( 0, 1000, 500), false );
   // way fewer basepairs than viewport pixel width
   BOOST_CHECK_EQUAL(s.is_sequence_renderable( 0, 10, 500), true);
+
+  BOOST_CHECK_CLOSE((double)s.get_pixel_width(0, 100, 100), 1.0, 1e-6);
+  BOOST_CHECK_CLOSE((double)s.get_pixel_width(0, 1000, 100), 10.0, 1e-6);
 }
 
 BOOST_AUTO_TEST_CASE( glsequence_sequence )