X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Frenderer%2FContactGeometry.java;h=ad741ff3f7a8b9db277e3d88addd6bbe122e5fba;hb=f3d6a13271e3f34dfb4e40d6a2a7df1d392f8014;hp=0e5107abba20dff67a5eee2f1bad0ddb836987ae;hpb=4cf91ec17ae81e5f4be97aacfb171e70add999c3;p=jalview.git diff --git a/src/jalview/renderer/ContactGeometry.java b/src/jalview/renderer/ContactGeometry.java index 0e5107a..ad741ff 100644 --- a/src/jalview/renderer/ContactGeometry.java +++ b/src/jalview/renderer/ContactGeometry.java @@ -2,21 +2,39 @@ package jalview.renderer; import java.util.Iterator; +import jalview.datamodel.ColumnSelection; import jalview.datamodel.ContactListI; +import jalview.datamodel.HiddenColumns; +import jalview.renderer.ContactGeometry.contactInterval; +/** + * encapsulate logic for mapping between positions in a ContactList and their + * rendered representation in a given number of pixels. + * + * @author jprocter + * + */ public class ContactGeometry { + + final ContactListI contacts; + final int pixels_step; final double contacts_per_pixel; final int contact_height; - public ContactGeometry(ContactListI contacts, int graphHeight) + final int graphHeight; + + public ContactGeometry(final ContactListI contacts, int graphHeight) { + this.contacts=contacts; + this.graphHeight = graphHeight; contact_height = contacts.getContactHeight(); // fractional number of contacts covering each pixel - contacts_per_pixel = ((double) contact_height) / ((double) graphHeight); + contacts_per_pixel = (graphHeight < 1) ? contact_height + : ((double) contact_height) / ((double) graphHeight); if (contacts_per_pixel >= 1) { @@ -50,6 +68,52 @@ public class ContactGeometry public final int pStart; public final int pEnd; + + } + /** + * + * @param columnSelection + * @param ci + * @param visibleOnly - when true, only test intersection of visible columns given matrix range + * @return true if the range on the matrix specified by ci intersects with selected columns in the ContactListI's reference frame. + */ + + boolean intersects(contactInterval ci, ColumnSelection columnSelection, + HiddenColumns hiddenColumns, boolean visibleOnly) + { + boolean rowsel = false; + final int[] mappedRange = contacts.getMappedPositionsFor(ci.cStart, + ci.cEnd); + if (mappedRange == null) + { + return false; + } + for (int p = 0; p < mappedRange.length && !rowsel; p += 2) + { + boolean containsHidden = false; + if (visibleOnly && hiddenColumns != null + && hiddenColumns.hasHiddenColumns()) + { + // TODO: turn into function on hiddenColumns and create test !! + Iterator viscont = hiddenColumns.getVisContigsIterator( + mappedRange[p], mappedRange[p + 1], false); + containsHidden = !viscont.hasNext(); + if (!containsHidden) + { + for (int[] interval = viscont.next(); viscont + .hasNext(); rowsel |= columnSelection + .intersects(interval[p], interval[p + 1])) + ; + } + } + else + { + rowsel = columnSelection.intersects(mappedRange[p], + mappedRange[p + 1]); + } + } + return rowsel; + } /** @@ -70,6 +134,25 @@ public class ContactGeometry 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 iterateOverContactIntervals( int graphHeight) {