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)
{
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;
+ }
+ boolean containsHidden=false;
+ if (visibleOnly && hiddenColumns!=null && hiddenColumns.hasHiddenColumns())
+ {
+ // TODO: turn into function on hiddenColumns and create test !!
+ Iterator<int[]> viscont = hiddenColumns
+ .getVisContigsIterator(mappedRange[0], mappedRange[1], false);
+ containsHidden = !viscont.hasNext();
+ if (!containsHidden)
+ {
+ for (int[] interval=viscont.next();viscont.hasNext();
+ rowsel |= columnSelection.intersects(interval[0],interval[1]))
+ ;
+ }
+ }
+ else
+ {
+ // if containsHidden is true mappedRange is not visible
+ if (containsHidden)
+ {
+ rowsel = columnSelection.intersects(mappedRange[0], mappedRange[1]);
+ }
+ }
+ return rowsel;
+
}
/**
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)
{