X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Frenderer%2FContactGeometry.java;h=9fd4de6cd02c2502ca94cfb106c4ab2c2d5059d4;hb=a19aa5efc2e64c17927336f422adde1837c27042;hp=0e5107abba20dff67a5eee2f1bad0ddb836987ae;hpb=4cf91ec17ae81e5f4be97aacfb171e70add999c3;p=jalview.git diff --git a/src/jalview/renderer/ContactGeometry.java b/src/jalview/renderer/ContactGeometry.java index 0e5107a..9fd4de6 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,56 @@ 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 +138,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) {