1 package jalview.renderer;
3 import java.util.Iterator;
5 import jalview.datamodel.ColumnSelection;
6 import jalview.datamodel.ContactListI;
7 import jalview.datamodel.HiddenColumns;
8 import jalview.renderer.ContactGeometry.contactInterval;
11 * encapsulate logic for mapping between positions in a ContactList and their
12 * rendered representation in a given number of pixels.
17 public class ContactGeometry
20 final ContactListI contacts;
22 final int pixels_step;
24 final double contacts_per_pixel;
26 final int contact_height;
28 final int graphHeight;
30 public ContactGeometry(final ContactListI contacts, int graphHeight)
32 this.contacts=contacts;
33 this.graphHeight = graphHeight;
34 contact_height = contacts.getContactHeight();
35 // fractional number of contacts covering each pixel
36 contacts_per_pixel = (graphHeight < 1) ? contact_height
37 : ((double) contact_height) / ((double) graphHeight);
39 if (contacts_per_pixel >= 1)
41 // many contacts rendered per pixel
46 // pixel height for each contact
47 pixels_step = (int) Math
48 .ceil(((double) graphHeight) / (double) contact_height);
52 public class contactInterval
54 public contactInterval(int cStart, int cEnd, int pStart, int pEnd)
62 // range on contact list
63 public final int cStart;
65 public final int cEnd;
68 public final int pStart;
70 public final int pEnd;
75 * @param columnSelection
77 * @param visibleOnly - when true, only test intersection of visible columns given matrix range
78 * @return true if the range on the matrix specified by ci intersects with selected columns in the ContactListI's reference frame.
81 boolean intersects(contactInterval ci, ColumnSelection columnSelection,
82 HiddenColumns hiddenColumns, boolean visibleOnly)
84 boolean rowsel = false;
85 final int[] mappedRange = contacts.getMappedPositionsFor(ci.cStart,
87 if (mappedRange == null)
91 for (int p = 0; p < mappedRange.length && !rowsel; p += 2)
93 boolean containsHidden = false;
94 if (visibleOnly && hiddenColumns != null
95 && hiddenColumns.hasHiddenColumns())
97 // TODO: turn into function on hiddenColumns and create test !!
98 Iterator<int[]> viscont = hiddenColumns.getVisContigsIterator(
99 mappedRange[p], mappedRange[p + 1], false);
100 containsHidden = !viscont.hasNext();
103 for (int[] interval = viscont.next(); viscont
104 .hasNext(); rowsel |= columnSelection
105 .intersects(interval[p], interval[p + 1]))
111 rowsel = columnSelection.intersects(mappedRange[p],
125 public contactInterval mapFor(int pStart, int pEnd)
127 int cStart = (int) Math.floor(pStart * contacts_per_pixel);
128 contactInterval ci = new contactInterval(cStart,
129 (int) Math.min(contact_height,
131 cStart + (pEnd - pStart) * contacts_per_pixel)),
138 * return the cell containing given pixel
141 * @return range for pCEntre
143 public contactInterval mapFor(int pCentre)
145 int pStart = Math.max(pCentre - pixels_step, 0);
146 int pEnd = Math.min(pStart + pixels_step, graphHeight);
147 int cStart = (int) Math.floor(pStart * contacts_per_pixel);
148 contactInterval ci = new contactInterval(cStart,
149 (int) Math.min(contact_height,
150 Math.ceil(cStart + (pixels_step) * contacts_per_pixel)),
156 public Iterator<contactInterval> iterateOverContactIntervals(
159 // NOT YET IMPLEMENTED
161 // int cstart = 0, cend;
164 // eht = y2 - graphHeight; ht >= eht; ht -= pixels_step)
166 // cstart = (int) Math.floor(((double) y2 - ht) * contacts_per_pixel);
167 // cend = (int) Math.min(contact_height,
168 // Math.ceil(cstart + contacts_per_pixel * pixels_step));
170 // return new Iterator<contactIntervals>() {
173 // public boolean hasNext()
175 // // TODO Auto-generated method stub
180 // public contactIntervals next()
182 // // TODO Auto-generated method stub