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;
76 * @param columnSelection
79 * - when true, only test intersection of visible columns given
81 * @return true if the range on the matrix specified by ci intersects with
82 * selected columns in the ContactListI's reference frame.
85 boolean intersects(contactInterval ci, ColumnSelection columnSelection,
86 HiddenColumns hiddenColumns, boolean visibleOnly)
88 boolean rowsel = false;
89 final int[] mappedRange = contacts.getMappedPositionsFor(ci.cStart,
91 if (mappedRange == null)
95 for (int p = 0; p < mappedRange.length && !rowsel; p += 2)
97 boolean containsHidden = false;
98 if (visibleOnly && hiddenColumns != null
99 && hiddenColumns.hasHiddenColumns())
101 // TODO: turn into function on hiddenColumns and create test !!
102 Iterator<int[]> viscont = hiddenColumns.getVisContigsIterator(
103 mappedRange[p], mappedRange[p + 1], false);
104 containsHidden = !viscont.hasNext();
107 for (int[] interval = viscont.next(); viscont
108 .hasNext(); rowsel |= columnSelection
109 .intersects(interval[p], interval[p + 1]))
115 rowsel = columnSelection.intersects(mappedRange[p],
129 public contactInterval mapFor(int pStart, int pEnd)
131 int cStart = (int) Math.floor(pStart * contacts_per_pixel);
132 contactInterval ci = new contactInterval(cStart,
133 (int) Math.min(contact_height,
135 cStart + (pEnd - pStart) * contacts_per_pixel)),
142 * return the cell containing given pixel
145 * @return range for pCEntre
147 public contactInterval mapFor(int pCentre)
149 int pStart = Math.max(pCentre - pixels_step, 0);
150 int pEnd = Math.min(pStart + pixels_step, graphHeight);
151 int cStart = (int) Math.floor(pStart * contacts_per_pixel);
152 contactInterval ci = new contactInterval(cStart,
153 (int) Math.min(contact_height,
154 Math.ceil(cStart + (pixels_step) * contacts_per_pixel)),
160 public Iterator<contactInterval> iterateOverContactIntervals(
163 // NOT YET IMPLEMENTED
165 // int cstart = 0, cend;
168 // eht = y2 - graphHeight; ht >= eht; ht -= pixels_step)
170 // cstart = (int) Math.floor(((double) y2 - ht) * contacts_per_pixel);
171 // cend = (int) Math.min(contact_height,
172 // Math.ceil(cstart + contacts_per_pixel * pixels_step));
174 // return new Iterator<contactIntervals>() {
177 // public boolean hasNext()
179 // // TODO Auto-generated method stub
184 // public contactIntervals next()
186 // // TODO Auto-generated method stub