Merge branch 'develop' into feature/JAL-1713_overviewInProject
[jalview.git] / src / jalview / renderer / ContactGeometry.java
diff --git a/src/jalview/renderer/ContactGeometry.java b/src/jalview/renderer/ContactGeometry.java
new file mode 100644 (file)
index 0000000..4aef1d8
--- /dev/null
@@ -0,0 +1,128 @@
+package jalview.renderer;
+
+import java.util.Iterator;
+
+import jalview.datamodel.ContactListI;
+
+public class ContactGeometry
+{
+  final int pixels_step;
+
+  final double contacts_per_pixel;
+
+  final int contact_height;
+
+  final int graphHeight;
+
+  public ContactGeometry(ContactListI contacts, int graphHeight)
+  {
+    this.graphHeight = graphHeight;
+    contact_height = contacts.getContactHeight();
+    // fractional number of contacts covering each pixel
+    contacts_per_pixel = (graphHeight < 1) ? contact_height
+            : ((double) contact_height) / ((double) graphHeight);
+
+    if (contacts_per_pixel >= 1)
+    {
+      // many contacts rendered per pixel
+      pixels_step = 1;
+    }
+    else
+    {
+      // pixel height for each contact
+      pixels_step = (int) Math
+              .ceil(((double) graphHeight) / (double) contact_height);
+    }
+  }
+
+  public class contactInterval
+  {
+    public contactInterval(int cStart, int cEnd, int pStart, int pEnd)
+    {
+      this.cStart = cStart;
+      this.cEnd = cEnd;
+      this.pStart = pStart;
+      this.pEnd = pEnd;
+    }
+
+    // range on contact list
+    public final int cStart;
+
+    public final int cEnd;
+
+    // range in pixels
+    public final int pStart;
+
+    public final int pEnd;
+  }
+
+  /**
+   * 
+   * @param pStart
+   * @param pEnd
+   * @return range for
+   */
+  public contactInterval mapFor(int pStart, int pEnd)
+  {
+    int cStart = (int) Math.floor(pStart * contacts_per_pixel);
+    contactInterval ci = new contactInterval(cStart,
+            (int) Math.min(contact_height,
+                    Math.ceil(
+                            cStart + (pEnd - pStart) * contacts_per_pixel)),
+            pStart, pEnd);
+
+    return ci;
+  }
+
+  /**
+   * return the cell containing given pixel
+   * 
+   * @param pCentre
+   * @return range for pCEntre
+   */
+  public contactInterval mapFor(int pCentre)
+  {
+    int pStart = Math.max(pCentre - pixels_step, 0);
+    int pEnd = Math.min(pStart + pixels_step, graphHeight);
+    int cStart = (int) Math.floor(pStart * contacts_per_pixel);
+    contactInterval ci = new contactInterval(cStart,
+            (int) Math.min(contact_height,
+                    Math.ceil(cStart + (pixels_step) * contacts_per_pixel)),
+            pStart, pEnd);
+
+    return ci;
+  }
+
+  public Iterator<contactInterval> iterateOverContactIntervals(
+          int graphHeight)
+  {
+    // NOT YET IMPLEMENTED
+    return null;
+    // int cstart = 0, cend;
+    //
+    // for (int ht = y2,
+    // eht = y2 - graphHeight; ht >= eht; ht -= pixels_step)
+    // {
+    // cstart = (int) Math.floor(((double) y2 - ht) * contacts_per_pixel);
+    // cend = (int) Math.min(contact_height,
+    // Math.ceil(cstart + contacts_per_pixel * pixels_step));
+    //
+    // return new Iterator<contactIntervals>() {
+    //
+    // @Override
+    // public boolean hasNext()
+    // {
+    // // TODO Auto-generated method stub
+    // return false;
+    // }
+    //
+    // @Override
+    // public contactIntervals next()
+    // {
+    // // TODO Auto-generated method stub
+    // return null;
+    // }
+    //
+    // }
+  }
+}
\ No newline at end of file