/*
* EuroCarbDB, a framework for carbohydrate bioinformatics
*
* Copyright (c) 2006-2009, Eurocarb project, or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
* A copy of this license accompanies this distribution in the file LICENSE.txt.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* Last commit: $Rev: 1210 $ by $Author: glycoslave $ on $Date:: 2009-06-12 #$
*/
package org.eurocarbdb.application.glycanbuilder;
import java.util.*;
import java.awt.Rectangle;
import java.awt.Dimension;
import java.awt.Point;
import static org.eurocarbdb.application.glycanbuilder.Geometry.*;
/**
Objects of this class are used to compute and store the bounding
box of a residue. The bounding boxes are used to identify the
position of a residue in the display area.
@see GlycanRenderer
@see ResidueRenderer
@author Alessio Ceroni (a.ceroni@imperial.ac.uk)
*/
public class BBoxManager {
protected GraphicOptions theGraphicOptions;
protected HashMap<Residue,Rectangle> parent_bboxes;
protected HashMap<Residue,Rectangle> current_bboxes;
protected HashMap<Residue,Rectangle> border_bboxes;
protected HashMap<Residue,Rectangle> complete_bboxes;
protected HashMap<Residue,Rectangle> support_bboxes;
protected HashMap<Residue,Vector<Residue>> linked_residues;
//
/**
Default constructor.
*/
public BBoxManager() {
parent_bboxes = new HashMap<Residue,Rectangle>();
current_bboxes = new HashMap<Residue,Rectangle>();
border_bboxes = new HashMap<Residue,Rectangle>();
complete_bboxes = new HashMap<Residue,Rectangle>();
support_bboxes = new HashMap<Residue,Rectangle>();
linked_residues = new HashMap<Residue,Vector<Residue>>();
}
/**
Return the graphic options used to determine the bounding box
size.
*/
public GraphicOptions getGraphicOptions() {
return theGraphicOptions;
}
/**
Set the graphic options used to determine the bounding box
size.
*/
public void setGraphicOptions(GraphicOptions opt) {
theGraphicOptions = opt;
}
//----------------
// member access
/**
Return an iterator over the set of bounding boxes.
*/
public Iterator<Map.Entry<Residue,Rectangle> > iterator() {
return current_bboxes.entrySet().iterator();
}
/**
Clear all fields.
*/
public void reset() {
parent_bboxes.clear();
current_bboxes.clear();
border_bboxes.clear();
complete_bboxes.clear();
support_bboxes.clear();
linked_residues.clear();
}
/**
Return the set of residues that are shown at the same position.
Used to represent multiple residues with uncertain
connectivity.
*/
public Vector<Residue> getLinkedResidues(Residue node) {
Vector<Residue> ret = linked_residues.get(node);
return ret==null ?new Vector<Residue>() :ret;
}
/**
Link all the residues in the subtree rooted at
<code>root_other</code> with <code>dest</code>
@see #getLinkedResidues
*/
public void linkSubtree(Residue dest, Residue root_other) {
if( dest!=root_other ) {
if( linked_residues.get(dest)==null )
linked_residues.put(dest,new Union<Residue>(root_other));
else
linked_residues.get(dest).add(root_other);
}
for( Linkage l : root_other.getChildrenLinkages() )
linkSubtree(dest,l.getChildResidue());
}
/**
Link all the residues in the subtree rooted at
<code>root_other</code> with the corresponding residues in the
subtree rooted at <code>root_dest</code>. The two subtrees must
have the same topology.
@see #getLinkedResidues
*/
public void linkSubtrees(Residue root_dest, Residue root_other) throws Exception {
if( root_dest==null )
return;
if( !root_dest.subtreeEquals(root_other) )
throw new Exception("Subtrees do not match");
linkSubtreesPVT(root_dest,root_other);
}
private void linkSubtreesPVT(Residue root_dest, Residue root_other) {
if( linked_residues.get(root_dest)==null )
linked_residues.put(root_dest,new Union<Residue>(root_other));
else
linked_residues.get(root_dest).add(root_other);
for( int i=0; i<root_dest.getNoChildren(); i++ )
linkSubtreesPVT(root_dest.getLinkageAt(i).getChildResidue(),root_other.getLinkageAt(i).getChildResidue());
}
/**
Return the bounding box occupied by a structure.
*/
public Rectangle getBBox(Glycan structure, boolean show_redend) {
if( structure==null )
return null;
return union(getComplete(structure.getRoot(show_redend)),getComplete(structure.getBracket()));
}
/**
Initialize all the bounding boxes corresponding to a residue.
*/
public void setAllBBoxes(Residue node, Rectangle bbox) {
setParent(node,new Rectangle(bbox));
setCurrent(node,new Rectangle(bbox));
setBorder(node,new Rectangle(bbox));
setComplete(node,new Rectangle(bbox));
setSupport(node,new Rectangle(bbox));
}
/**
Set the bounding box of the parent residue.
*/
public void setParent(Residue node, Rectangle bbox) {
if( node!=null && bbox!=null )
parent_bboxes.put(node,new Rectangle(bbox));
}
/**
Get the bounding box of the parent residue.
*/
public Rectangle getParent(Residue node) {
if( node==null )
return null;
return parent_bboxes.get(node);
}
/**
Set the bounding box of the residue.
*/
public void setCurrent(Residue node, Rectangle bbox) {
if( node!=null && bbox!=null )
current_bboxes.put(node,new Rectangle(bbox));
}
/**
Get the bounding box of the residue.
*/
public Rectangle getCurrent(Residue node) {
if( node==null )
return null;
return current_bboxes.get(node);
}
/**
Set the bounding box of the residue including the children
position on its border.
*/
public void setBorder(Residue node, Rectangle bbox) {
if( node!=null && bbox!=null )
border_bboxes.put(node,new Rectangle(bbox));
}
/**
Get the bounding box of the residue including the children
position on its border.
*/
public Rectangle getBorder(Residue node) {
if( node==null )
return null;
return border_bboxes.get(node);
}
/**
Set the bounding box of the subtree rooted at the residue.
*/
public void setComplete(Residue node, Rectangle bbox) {
if( node!=null && bbox!=null )
complete_bboxes.put(node,new Rectangle(bbox));
}
/**
Get the bounding box of the subtree rooted at the residue.
*/
public Rectangle getComplete(Residue node) {
if( node==null )
return null;
return complete_bboxes.get(node);
}
/**
Set the bounding box used to compute the spatial orientation of
the residue.
*/
public void setSupport(Residue node, Rectangle bbox) {
if( node!=null && bbox!=null )
support_bboxes.put(node,new Rectangle(bbox));
}
/**
Get the bounding box used to compute the spatial orientation of
the residue.
*/
public Rectangle getSupport(Residue node) {
if( node==null )
return null;
return support_bboxes.get(node);
}
//----------------
// functions
/**
Return the residue whose bounding box contains the point.
*/
public Residue getNodeAtPoint(Point p) {
if( p==null )
return null;
for( Iterator<Map.Entry<Residue,Rectangle> > i=current_bboxes.entrySet().iterator(); i.hasNext(); ) {
Map.Entry<Residue,Rectangle> e = i.next();
if( e.getValue().contains(p) )
return e.getKey();
}
return null;
}
/**
Return the residues whose bounding boxes intersect the given
rectangle.
*/
public Vector<Residue> getNodesInside(Rectangle r) {
if( r==null )
return null;
Vector<Residue> nodes = new Vector<Residue>();
for( Iterator<Map.Entry<Residue,Rectangle> > i=current_bboxes.entrySet().iterator(); i.hasNext(); ) {
Map.Entry<Residue,Rectangle> e = i.next();
if( r.intersects(e.getValue()) )
nodes.add(e.getKey());
}
return nodes;
}
/**
Return the union of all the bounding boxes of the subtrees
rooted at the given residues.
*/
public Rectangle getComplete(List<Residue> nodes) {
Rectangle bbox = null;
for(Residue r: nodes)
bbox = Geometry.union(getComplete(r),bbox);
return bbox;
}
/**
Return the bounding box of the central residue in a list of
children. If the number of residues is even two bounding boxes
are combined.
*/
public Rectangle getCurrent(List<Residue> nodes) {
int n = nodes.size();
if( n==0 )
return null;
if( (n%2)==1 )
return getCurrent(nodes.get(n/2));
return Geometry.union(getCurrent(nodes.get(n/2-1)),getCurrent(nodes.get(n/2)));
}
private Rectangle getCurrentComplete(List<Residue> nodes) {
Rectangle bbox = null;
if( nodes!=null ) {
for( Residue r : nodes )
bbox = Geometry.union(bbox,getCurrent(r));
}
return bbox;
}
private Vector<Rectangle> getAll(List<Residue> v) throws Exception {
Vector<Rectangle> ret = new Vector<Rectangle>();
if( v!=null ) {
for( Residue r : v )
getAll(r,ret);
}
return ret;
}
private Vector<Rectangle> getAll(Residue r) throws Exception {
Vector<Rectangle> ret = new Vector<Rectangle>();
getAll(r,ret);
return ret;
}
private void getAll(Residue r, List<Rectangle> buffer) throws Exception {
if( r==null )
throw new Exception("Empty node");
Rectangle cur = getCurrent(r);
if( cur==null )
throw new Exception("Empty bbox");
buffer.add(cur);
for( Linkage l : r.getChildrenLinkages() )
getAll(l.getChildResidue(),buffer);
}
/**
Return the difference in radiants between two angles going
clockwise.
*/
static protected double distanceCW(double ref_angle, double other_angle) {
if( other_angle>ref_angle )
return (other_angle-ref_angle);
return (2.*Math.PI+other_angle-ref_angle);
}
/**
Return the difference in radiants between two angles going
counter-clockwise.
*/
static protected double distanceCCW(double ref_angle, double other_angle) {
if( other_angle<ref_angle )
return (ref_angle-other_angle);
return (2.*Math.PI+ref_angle-other_angle);
}
/**
Return the angle of the vector joining the centers of the
bounding boxes of the two residues.
*/
protected double getScreenAngle(Residue node, Residue parent) {
Rectangle node_bbox = getCurrent(node);
Rectangle par_bbox = getCurrent(parent);
if( node_bbox==null || par_bbox==null )
return 0.;
return angle(center(node_bbox),center(par_bbox));
}
protected Residue getNearestCW(Residue node, Collection<Residue> brothers) {
if( node==null )
return null;
Residue parent = node.getParent();
if( parent==null )
return null;
double best_dist = 0.;
Residue best_residue = null;
double node_angle = getScreenAngle(node,parent);
for( Residue other : brothers ) {
double other_angle = getScreenAngle(other,parent);
double dist = distanceCW(node_angle,other_angle);
if( dist<Math.PI/2 ) {
if( best_residue==null || dist<best_dist ) {
best_residue = other;
best_dist = dist;
}
}
}
return best_residue;
}
protected Residue getNearestCCW(Residue node, Collection<Residue> brothers) {
if( node==null )
return null;
Residue parent = node.getParent();
if( parent==null )
return null;
double best_dist = 0.;
Residue best_residue = null;
double node_angle = getScreenAngle(node,parent);
for( Residue other : brothers ) {
double other_angle = getScreenAngle(other,parent);
double dist = distanceCCW(node_angle,other_angle);
if( dist<Math.PI/2 ) {
if( best_residue==null || dist<best_dist ) {
best_residue = other;
best_dist = dist;
}
}
}
return best_residue;
}
protected Residue getNearestUp(Residue node) {
return getNearestUp(node,current_bboxes.keySet().iterator());
}
protected Residue getNearestUp(Residue node, Collection<Residue> brothers) {
return getNearestUp(node,brothers.iterator());
}
protected Residue getNearestUp(Residue node, Iterator<Residue> first) {
if( node==null || first==null )
return null;
Rectangle cur_rect = getCurrent(node);
Residue best_node = null;
Rectangle best_rect = null;
double best_dist = 0.;
for( Iterator<Residue> i=first; i.hasNext(); ) {
Residue nav_node = i.next();
Rectangle nav_rect = getCurrent(nav_node);
if( isUp(nav_rect,cur_rect) ) {
double nav_dist = distance(nav_rect,cur_rect);
if( best_node==null || nav_dist<best_dist || (nav_dist==best_dist && best_rect.x>nav_rect.x) ) {
best_node = nav_node;
best_rect = nav_rect;
best_dist = nav_dist;
}
}
}
return best_node;
}
protected Residue getNearestDown(Residue node) {
return getNearestDown(node,current_bboxes.keySet().iterator());
}
protected Residue getNearestDown(Residue node, Collection<Residue> brothers) {
return getNearestDown(node,brothers.iterator());
}
protected Residue getNearestDown(Residue node, Iterator<Residue> first) {
if( node==null || first==null )
return null;
Rectangle cur_rect = getCurrent(node);
Residue best_node = null;
Rectangle best_rect = null;
double best_dist = 0.;
for( Iterator<Residue> i=first; i.hasNext(); ) {
Residue nav_node = i.next();
Rectangle nav_rect = getCurrent(nav_node);
if( isDown(nav_rect,cur_rect) ) {
double nav_dist = distance(nav_rect,cur_rect);
if( best_node==null || nav_dist<best_dist || (nav_dist==best_dist && best_rect.x>nav_rect.x) ) {
best_node = nav_node;
best_rect = nav_rect;
best_dist = nav_dist;
}
}
}
return best_node;
}
protected Residue getNearestLeft(Residue node) {
return getNearestLeft(node,current_bboxes.keySet().iterator());
}
protected Residue getNearestLeft(Residue node, Collection<Residue> brothers) {
return getNearestLeft(node,brothers.iterator());
}
protected Residue getNearestLeft(Residue node, Iterator<Residue> first) {
if( node==null || first==null )
return null;
Rectangle cur_rect = getCurrent(node);
Residue best_node = null;
Rectangle best_rect = null;
double best_dist = 0.;
for( Iterator<Residue> i=first; i.hasNext(); ) {
Residue nav_node = i.next();
Rectangle nav_rect = getCurrent(nav_node);
if( isLeft(nav_rect,cur_rect) ) {
double nav_dist = distance(nav_rect,cur_rect);
if( best_node==null || nav_dist<best_dist || (nav_dist==best_dist && best_rect.y>nav_rect.y) ) {
best_node = nav_node;
best_rect = nav_rect;
best_dist = nav_dist;
}
}
}
return best_node;
}
protected Residue getNearestRight(Residue node) {
return getNearestRight(node,current_bboxes.keySet().iterator());
}
protected Residue getNearestRight(Residue node, Collection<Residue> brothers) {
return getNearestRight(node,brothers.iterator());
}
protected Residue getNearestRight(Residue node, Iterator<Residue> first) {
if( node==null || first==null )
return null;
Rectangle cur_rect = getCurrent(node);
Residue best_node = null;
Rectangle best_rect = null;
double best_dist = 0.;
for( Iterator<Residue> i=first; i.hasNext(); ) {
Residue nav_node = i.next();
Rectangle nav_rect = getCurrent(nav_node);
if( isRight(nav_rect,cur_rect) ) {
double nav_dist = distance(nav_rect,cur_rect);
if( best_node==null || nav_dist<best_dist || (nav_dist==best_dist && best_rect.y>nav_rect.y) ) {
best_node = nav_node;
best_rect = nav_rect;
best_dist = nav_dist;
}
}
}
return best_node;
}
//----------------
// traslation
/**
Translate the bounding boxes of the given residues by a
specified displacement.
*/
public void translate(int sx, int sy, List<Residue> nodes) {
if( nodes!=null ) {
for(Iterator<Residue> i=nodes.iterator(); i.hasNext(); )
translate(sx,sy,i.next());
}
}
/**
Translate the bounding boxes of the given residues by a
specified displacement.
*/
public void translate(Dimension s, List<Residue> nodes) {
if( nodes!=null ) {
for(Iterator<Residue> i=nodes.iterator(); i.hasNext(); )
translate(s,i.next());
}
}
/**
Translate the bounding boxes of all the residues of the given
structures by a specified displacement.
*/
public void translate(Dimension s, Collection<Glycan> c) {
translate(s.width,s.height,c);
}
/**
Translate the bounding boxes of all the residues of the given
structures by a specified displacement.
*/
public void translate(int sx, int sy, Collection<Glycan> c) {
for(Glycan g : c)
translate(sx,sy,g);
}
/**
Translate the bounding boxes of all the residues of the given
structure by a specified displacement.
*/
public void translate(Dimension s, Glycan g) {
if( s!=null )
translate(s.width,s.height,g);
}
/**
Translate the bounding boxes of all the residues of the given
structure by a specified displacement.
*/
public void translate(int sx, int sy, Glycan g) {
if( g!=null ) {
translate(sx,sy,g.getRoot());
translate(sx,sy,g.getBracket());
}
}
/**
Translate the bounding box of the residue by a specified
displacement.
*/
public void translate(Dimension s, Residue node) {
if( s!=null )
translate(s.width,s.height,node);
}
/**
Translate the bounding box of the residue by a specified
displacement.
*/
public void translate(int sx, int sy, Residue node) {
if( node!=null ) {
translate(sx,sy,parent_bboxes.get(node));
translate(sx,sy,current_bboxes.get(node));
translate(sx,sy,border_bboxes.get(node));
translate(sx,sy,complete_bboxes.get(node));
translate(sx,sy,support_bboxes.get(node));
for(Iterator<Linkage> i=node.iterator(); i.hasNext(); )
translate(sx,sy,i.next().getChildResidue());
}
}
/**
Translate the coordinate of a rectangle by a specified
displacement.
*/
static public void translate(int sx, int sy, Rectangle r) {
if( r!=null )
r.translate(sx,sy);
}
//-------------
// alignment
private Vector<Rectangle> singleton(Rectangle r) {
Vector<Rectangle> ret = new Vector<Rectangle>();
if( r!=null )
ret.add(r);
return ret;
}
private Vector<Residue> singleton(Residue r) {
Vector<Residue> ret = new Vector<Residue>();
if( r!=null )
ret.add(r);
return ret;
}
static private void assertAlignment(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int space) throws Exception{
if( ref_all_bboxes==null || ref_all_bboxes.size()==0 )
throw new Exception("Empty reference bbox set");
if( ref_sup_bbox==null )
throw new Exception("Empty reference bbox");
if( cur_all_bboxes==null || cur_all_bboxes.size()==0 )
throw new Exception("Empty current bbox set");
if( cur_sup_bbox==null )
throw new Exception("Empty current bbox");
if( space<0 )
throw new Exception("Negative distance");
}
// --- VERTICAL
protected void alignLeftsOnTop(List<Residue> ref_nodes, List<Residue> nodes, int space) throws Exception { alignLeftsOnTop(getAll(ref_nodes), getCurrent(ref_nodes), nodes, space); }
protected void alignLeftsOnTop(Residue ref_node, List<Residue> nodes, int space) throws Exception { alignLeftsOnTop(getAll(ref_node), getCurrent(ref_node), nodes, space); }
protected void alignLeftsOnTop(Rectangle ref_bbox, List<Residue> nodes, int space) throws Exception { alignLeftsOnTop(singleton(ref_bbox), ref_bbox, nodes, space); }
protected void alignLeftsOnTop(Residue ref_node, Residue node, int space) throws Exception { alignLeftsOnTop(getAll(ref_node), getCurrent(ref_node), singleton(node), space); }
protected void alignLeftsOnTop(Rectangle ref_bbox, Residue node, int space) throws Exception { alignLeftsOnTop(singleton(ref_bbox), ref_bbox, singleton(node), space); }
protected void alignLeftsOnTop(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignLeftsOnTop(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
protected void alignLeftsOnTop(List<Residue> ref_sup_nodes, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignLeftsOnTop(new Union<Rectangle>(getAll(ref_sup_nodes)).and(getAll(ref_nodes)),getCurrent(ref_sup_nodes),getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
private void alignLeftsOnTop(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Residue> nodes, int space) throws Exception {
alignLeftsOnTop(ref_all_bboxes,ref_sup_bbox,getAll(nodes),getCurrent(nodes),nodes,space);
}
private void alignLeftsOnTop(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int space) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,space);
translate(left(ref_sup_bbox)-left(cur_sup_bbox),0,nodes); // align left
translate(0,shiftToTop(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,space),nodes); // put on top
}
}
protected void alignLeftsOnBottom(List<Residue> ref_nodes, List<Residue> nodes, int space) throws Exception { alignLeftsOnBottom(getAll(ref_nodes), getCurrent(ref_nodes), nodes, space); }
protected void alignLeftsOnBottom(Residue ref_node, List<Residue> nodes, int space) throws Exception { alignLeftsOnBottom(getAll(ref_node), getCurrent(ref_node), nodes, space); }
protected void alignLeftsOnBottom(Rectangle ref_bbox, List<Residue> nodes, int space) throws Exception { alignLeftsOnBottom(singleton(ref_bbox), ref_bbox, nodes, space); }
protected void alignLeftsOnBottom(Residue ref_node, Residue node, int space) throws Exception { alignLeftsOnBottom(getAll(ref_node), getCurrent(ref_node), singleton(node), space); }
protected void alignLeftsOnBottom(Rectangle ref_bbox, Residue node, int space) throws Exception { alignLeftsOnBottom(singleton(ref_bbox), ref_bbox, singleton(node), space); }
protected void alignLeftsOnBottom(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignLeftsOnBottom(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
protected void alignLeftsOnBottom(List<Residue> ref_sup_nodes, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignLeftsOnBottom(new Union<Rectangle>(getAll(ref_sup_nodes)).and(getAll(ref_nodes)),getCurrent(ref_sup_nodes),getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
private void alignLeftsOnBottom(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Residue> nodes, int space) throws Exception {
alignLeftsOnBottom(ref_all_bboxes,ref_sup_bbox,getAll(nodes),getCurrent(nodes),nodes,space);
}
private void alignLeftsOnBottom(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int space) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,space);
translate(left(ref_sup_bbox)-left(cur_sup_bbox),0,nodes); // align left
translate(0,shiftToBottom(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,space),nodes); // put on bottom
}
}
protected void alignRightsOnTop(List<Residue> ref_nodes, List<Residue> nodes, int space) throws Exception { alignRightsOnTop(getAll(ref_nodes), getCurrent(ref_nodes), nodes, space); }
protected void alignRightsOnTop(Residue ref_node, List<Residue> nodes, int space) throws Exception { alignRightsOnTop(getAll(ref_node), getCurrent(ref_node), nodes, space); }
protected void alignRightsOnTop(Rectangle ref_bbox, List<Residue> nodes, int space) throws Exception { alignRightsOnTop(singleton(ref_bbox), ref_bbox, nodes, space); }
protected void alignRightsOnTop(Residue ref_node, Residue node, int space) throws Exception { alignRightsOnTop(getAll(ref_node), getCurrent(ref_node), singleton(node), space); }
protected void alignRightsOnTop(Rectangle ref_bbox, Residue node, int space) throws Exception { alignRightsOnTop(singleton(ref_bbox), ref_bbox, singleton(node), space); }
protected void alignRightsOnTop(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignRightsOnTop(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
protected void alignRightsOnTop(List<Residue> ref_sup_nodes, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignRightsOnTop(new Union<Rectangle>(getAll(ref_sup_nodes)).and(getAll(ref_nodes)),getCurrent(ref_sup_nodes),getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
private void alignRightsOnTop(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Residue> nodes, int space) throws Exception {
alignRightsOnTop(ref_all_bboxes,ref_sup_bbox,getAll(nodes),getCurrent(nodes),nodes,space);
}
private void alignRightsOnTop(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int space) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,space);
translate(right(ref_sup_bbox)-right(cur_sup_bbox),0,nodes); // align right
translate(0,shiftToTop(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,space),nodes); // put on top
}
}
protected void alignRightsOnBottom(List<Residue> ref_nodes, List<Residue> nodes, int space) throws Exception { alignRightsOnBottom(getAll(ref_nodes), getCurrent(ref_nodes), nodes, space); }
protected void alignRightsOnBottom(Residue ref_node, List<Residue> nodes, int space) throws Exception { alignRightsOnBottom(getAll(ref_node), getCurrent(ref_node), nodes, space); }
protected void alignRightsOnBottom(Rectangle ref_bbox, List<Residue> nodes, int space) throws Exception { alignRightsOnBottom(singleton(ref_bbox), ref_bbox, nodes, space); }
protected void alignRightsOnBottom(Residue ref_node, Residue node, int space) throws Exception { alignRightsOnBottom(getAll(ref_node), getCurrent(ref_node), singleton(node), space); }
protected void alignRightsOnBottom(Rectangle ref_bbox, Residue node, int space) throws Exception { alignRightsOnBottom(singleton(ref_bbox), ref_bbox, singleton(node), space); }
protected void alignRightsOnBottom(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignRightsOnBottom(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
protected void alignRightsOnBottom(List<Residue> ref_sup_nodes, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignRightsOnBottom(new Union<Rectangle>(getAll(ref_sup_nodes)).and(getAll(ref_nodes)),getCurrent(ref_sup_nodes),getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
private void alignRightsOnBottom(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Residue> nodes, int space) throws Exception {
alignRightsOnBottom(ref_all_bboxes,ref_sup_bbox,getAll(nodes),getCurrent(nodes),nodes,space);
}
private void alignRightsOnBottom(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int space) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,space);
translate(right(ref_sup_bbox)-right(cur_sup_bbox),0,nodes); // align right
translate(0,shiftToBottom(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,space),nodes); // put on bottom
}
}
protected void alignCentersOnTop(List<Residue> ref_nodes, List<Residue> nodes, int space) throws Exception { alignCentersOnTop(getAll(ref_nodes), getCurrent(ref_nodes), nodes, space); }
protected void alignCentersOnTop(Residue ref_node, List<Residue> nodes, int space) throws Exception { alignCentersOnTop(getAll(ref_node), getCurrent(ref_node), nodes, space); }
protected void alignCentersOnTop(Rectangle ref_bbox, List<Residue> nodes, int space) throws Exception { alignCentersOnTop(singleton(ref_bbox), ref_bbox, nodes, space); }
protected void alignCentersOnTop(Residue ref_node, Residue node, int space) throws Exception { alignCentersOnTop(getAll(ref_node), getCurrent(ref_node), singleton(node), space); }
protected void alignCentersOnTop(Rectangle ref_bbox, Residue node, int space) throws Exception { alignCentersOnTop(singleton(ref_bbox), ref_bbox, singleton(node), space); }
protected void alignCentersOnTop(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignCentersOnTop(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
protected void alignCentersOnTop(List<Residue> ref_sup_nodes, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignCentersOnTop(new Union<Rectangle>(getAll(ref_sup_nodes)).and(getAll(ref_nodes)),getCurrent(ref_sup_nodes),getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
private void alignCentersOnTop(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Residue> nodes, int space) throws Exception {
alignCentersOnTop(ref_all_bboxes,ref_sup_bbox,getAll(nodes),getCurrent(nodes),nodes,space);
}
private void alignCentersOnTop(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int space) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,space);
translate(midx(ref_sup_bbox)-midx(cur_sup_bbox),0,nodes); // align center
translate(0,shiftToTop(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,space),nodes); // put on top
}
}
protected void alignCentersOnBottom(List<Residue> ref_nodes, List<Residue> nodes, int space) throws Exception { alignCentersOnBottom(getAll(ref_nodes), getCurrent(ref_nodes), nodes, space); }
protected void alignCentersOnBottom(Residue ref_node, List<Residue> nodes, int space) throws Exception { alignCentersOnBottom(getAll(ref_node), getCurrent(ref_node), nodes, space); }
protected void alignCentersOnBottom(Rectangle ref_bbox, List<Residue> nodes, int space) throws Exception { alignCentersOnBottom(singleton(ref_bbox), ref_bbox, nodes, space); }
protected void alignCentersOnBottom(Residue ref_node, Residue node, int space) throws Exception { alignCentersOnBottom(getAll(ref_node), getCurrent(ref_node), singleton(node), space); }
protected void alignCentersOnBottom(Rectangle ref_bbox, Residue node, int space) throws Exception { alignCentersOnBottom(singleton(ref_bbox), ref_bbox, singleton(node), space); }
protected void alignCentersOnBottom(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignCentersOnBottom(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
protected void alignCentersOnBottom(List<Residue> ref_sup_nodes, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignCentersOnBottom(new Union<Rectangle>(getAll(ref_sup_nodes)).and(getAll(ref_nodes)),getCurrent(ref_sup_nodes),getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
private void alignCentersOnBottom(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Residue> nodes, int space) throws Exception {
alignCentersOnBottom(ref_all_bboxes,ref_sup_bbox,getAll(nodes),getCurrent(nodes),nodes,space);
}
private void alignCentersOnBottom(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int space) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,space);
translate(midx(ref_sup_bbox)-midx(cur_sup_bbox),0,nodes); // align center
translate(0,shiftToBottom(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,space),nodes); // put on bottom
}
}
protected void alignCornersOnTopAtLeft(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> nodes, int xspace, int yspace) throws Exception {
alignCornersOnTopAtLeft(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrentComplete(nodes),nodes,xspace,yspace);
}
private void alignCornersOnTopAtLeft(List<Rectangle>ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int xspace, int yspace) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,xspace);
translate(left(ref_sup_bbox)-right(cur_sup_bbox)-xspace,0,nodes); // align corner
translate(0,shiftToTop(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,yspace),nodes); // put on top
}
}
protected void alignCornersOnTopAtRight(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> nodes, int xspace, int yspace) throws Exception {
alignCornersOnTopAtRight(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrentComplete(nodes),nodes,xspace,yspace);
}
private void alignCornersOnTopAtRight(List<Rectangle>ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int xspace, int yspace) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,xspace);
translate(right(ref_sup_bbox)-left(cur_sup_bbox)+xspace,0,nodes); // align center
translate(0,shiftToTop(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,yspace),nodes); // put on top
}
}
protected void alignCornersOnBottomAtLeft(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> nodes, int xspace, int yspace) throws Exception {
alignCornersOnBottomAtLeft(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrentComplete(nodes),nodes,xspace,yspace);
}
private void alignCornersOnBottomAtLeft(List<Rectangle>ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int xspace, int yspace) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,xspace);
translate(left(ref_sup_bbox)-right(cur_sup_bbox)-xspace,0,nodes); // align center
translate(0,shiftToBottom(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,yspace),nodes); // put on bottom
}
}
protected void alignCornersOnBottomAtRight(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> nodes, int xspace, int yspace) throws Exception {
alignCornersOnBottomAtRight(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrentComplete(nodes),nodes,xspace,yspace);
}
private void alignCornersOnBottomAtRight(List<Rectangle>ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int xspace, int yspace) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,xspace);
translate(right(ref_sup_bbox)-left(cur_sup_bbox)+xspace,0,nodes); // align center
translate(0,shiftToBottom(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,yspace),nodes); // put on bottom
}
}
private int shiftToTop(List<Rectangle> ref_bboxes, Rectangle ref_bbox, List<Rectangle> cur_bboxes, Rectangle cur_bbox, int space) throws Exception{
return shiftToTop(ref_bboxes,ref_bbox,cur_bboxes,cur_bbox,space,0);
}
private int shiftToTop(List<Rectangle> ref_bboxes, Rectangle ref_bbox, List<Rectangle> cur_bboxes, Rectangle cur_bbox, int space, int min_ref_space) throws Exception{
int toll = theGraphicOptions.NODE_SPACE/2-1;
int shift = top(ref_bbox) - Math.max(space,min_ref_space) - bottom(cur_bbox);
for( Rectangle cur : cur_bboxes )
for( Rectangle ref : ref_bboxes )
if( overlapx(cur,ref,toll) )
shift = Math.min(shift, top(ref) - space - bottom(cur));
return shift;
}
private int shiftToBottom(List<Rectangle> ref_bboxes, Rectangle ref_bbox, List<Rectangle> cur_bboxes, Rectangle cur_bbox, int space) throws Exception{
return shiftToBottom(ref_bboxes,ref_bbox,cur_bboxes,cur_bbox,space,0);
}
private int shiftToBottom(List<Rectangle> ref_bboxes, Rectangle ref_bbox, List<Rectangle> cur_bboxes, Rectangle cur_bbox, int space, int min_ref_space) throws Exception{
int toll = theGraphicOptions.NODE_SPACE/2-1;
int shift = bottom(ref_bbox) + Math.max(space,min_ref_space) - top(cur_bbox);
for( Rectangle cur : cur_bboxes )
for( Rectangle ref : ref_bboxes )
if( overlapx(cur,ref,toll) )
shift = Math.max(shift, bottom(ref) + space - top(cur));
return shift;
}
//--- HORIZONTAL
protected void alignTopsOnLeft(List<Residue> ref_nodes, List<Residue> nodes, int space) throws Exception { alignTopsOnLeft(getAll(ref_nodes), getCurrent(ref_nodes), nodes, space); }
protected void alignTopsOnLeft(Residue ref_node, List<Residue> nodes, int space) throws Exception { alignTopsOnLeft(getAll(ref_node), getCurrent(ref_node), nodes, space); }
protected void alignTopsOnLeft(Rectangle ref_bbox, List<Residue> nodes, int space) throws Exception { alignTopsOnLeft(singleton(ref_bbox), ref_bbox, nodes, space); }
protected void alignTopsOnLeft(Residue ref_node, Residue node, int space) throws Exception { alignTopsOnLeft(getAll(ref_node), getCurrent(ref_node), singleton(node), space); }
protected void alignTopsOnLeft(Rectangle ref_bbox, Residue node, int space) throws Exception { alignTopsOnLeft(singleton(ref_bbox), ref_bbox, singleton(node), space); }
protected void alignTopsOnLeft(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignTopsOnLeft(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
protected void alignTopsOnLeft(List<Residue> ref_sup_nodes, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignTopsOnLeft(new Union<Rectangle>(getAll(ref_sup_nodes)).and(getAll(ref_nodes)),getCurrent(ref_sup_nodes),getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
private void alignTopsOnLeft(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Residue> nodes, int space) throws Exception {
alignTopsOnLeft(ref_all_bboxes,ref_sup_bbox,getAll(nodes),getCurrent(nodes),nodes,space);
}
private void alignTopsOnLeft(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int space) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,space);
translate(0,top(ref_sup_bbox)-top(cur_sup_bbox),nodes); // align top
translate(shiftToLeft(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,space),0,nodes); // put on left
}
}
protected void alignTopsOnRight(List<Residue> ref_nodes, List<Residue> nodes, int space) throws Exception { alignTopsOnRight(getAll(ref_nodes), getCurrent(ref_nodes), nodes, space); }
protected void alignTopsOnRight(Residue ref_node, List<Residue> nodes, int space) throws Exception { alignTopsOnRight(getAll(ref_node), getCurrent(ref_node), nodes, space); }
protected void alignTopsOnRight(Rectangle ref_bbox, List<Residue> nodes, int space) throws Exception { alignTopsOnRight(singleton(ref_bbox), ref_bbox, nodes, space); }
protected void alignTopsOnRight(Residue ref_node, Residue node, int space) throws Exception { alignTopsOnRight(getAll(ref_node), getCurrent(ref_node), singleton(node), space); }
protected void alignTopsOnRight(Rectangle ref_bbox, Residue node, int space) throws Exception { alignTopsOnRight(singleton(ref_bbox), ref_bbox, singleton(node), space); }
protected void alignTopsOnRight(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignTopsOnRight(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
protected void alignTopsOnRight(List<Residue> ref_sup_nodes, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignTopsOnRight(new Union<Rectangle>(getAll(ref_sup_nodes)).and(getAll(ref_nodes)),getCurrent(ref_sup_nodes),getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
private void alignTopsOnRight(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Residue> nodes, int space) throws Exception {
alignTopsOnRight(ref_all_bboxes,ref_sup_bbox,getAll(nodes),getCurrent(nodes),nodes,space);
}
private void alignTopsOnRight(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int space) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,space);
translate(0,top(ref_sup_bbox)-top(cur_sup_bbox),nodes); // align top
translate(shiftToRight(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,space),0,nodes); // put on right
}
}
protected void alignBottomsOnLeft(List<Residue> ref_nodes, List<Residue> nodes, int space) throws Exception { alignBottomsOnLeft(getAll(ref_nodes), getCurrent(ref_nodes), nodes, space); }
protected void alignBottomsOnLeft(Residue ref_node, List<Residue> nodes, int space) throws Exception { alignBottomsOnLeft(getAll(ref_node), getCurrent(ref_node), nodes, space); }
protected void alignBottomsOnLeft(Rectangle ref_bbox, List<Residue> nodes, int space) throws Exception { alignBottomsOnLeft(singleton(ref_bbox), ref_bbox, nodes, space); }
protected void alignBottomsOnLeft(Residue ref_node, Residue node, int space) throws Exception { alignBottomsOnLeft(getAll(ref_node), getCurrent(ref_node), singleton(node), space); }
protected void alignBottomsOnLeft(Rectangle ref_bbox, Residue node, int space) throws Exception { alignBottomsOnLeft(singleton(ref_bbox), ref_bbox, singleton(node), space); }
protected void alignBottomsOnLeft(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignBottomsOnLeft(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
protected void alignBottomsOnLeft(List<Residue> ref_sup_nodes, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignBottomsOnLeft(new Union<Rectangle>(getAll(ref_sup_nodes)).and(getAll(ref_nodes)),getCurrent(ref_sup_nodes),getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
private void alignBottomsOnLeft(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Residue> nodes, int space) throws Exception {
alignBottomsOnLeft(ref_all_bboxes,ref_sup_bbox,getAll(nodes),getCurrent(nodes),nodes,space);
}
private void alignBottomsOnLeft(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int space) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,space);
translate(0,bottom(ref_sup_bbox)-bottom(cur_sup_bbox),nodes); // align bottom
translate(shiftToLeft(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,space),0,nodes); // put on left
}
}
protected void alignBottomsOnRight(List<Residue> ref_nodes, List<Residue> nodes, int space) throws Exception { alignBottomsOnRight(getAll(ref_nodes), getCurrent(ref_nodes), nodes, space); }
protected void alignBottomsOnRight(Residue ref_node, List<Residue> nodes, int space) throws Exception { alignBottomsOnRight(getAll(ref_node), getCurrent(ref_node), nodes, space); }
protected void alignBottomsOnRight(Rectangle ref_bbox, List<Residue> nodes, int space) throws Exception { alignBottomsOnRight(singleton(ref_bbox), ref_bbox, nodes, space); }
protected void alignBottomsOnRight(Residue ref_node, Residue node, int space) throws Exception { alignBottomsOnRight(getAll(ref_node), getCurrent(ref_node), singleton(node), space); }
protected void alignBottomsOnRight(Rectangle ref_bbox, Residue node, int space) throws Exception { alignBottomsOnRight(singleton(ref_bbox), ref_bbox, singleton(node), space); }
protected void alignBottomsOnRight(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignBottomsOnRight(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
protected void alignBottomsOnRight(List<Residue> ref_sup_nodes, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignBottomsOnRight(new Union<Rectangle>(getAll(ref_sup_nodes)).and(getAll(ref_nodes)),getCurrent(ref_sup_nodes),getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
private void alignBottomsOnRight(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Residue> nodes, int space) throws Exception {
alignBottomsOnRight(ref_all_bboxes,ref_sup_bbox,getAll(nodes),getCurrent(nodes),nodes,space);
}
private void alignBottomsOnRight(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int space) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,space);
translate(0,bottom(ref_sup_bbox)-bottom(cur_sup_bbox),nodes); // align bottom
translate(shiftToRight(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,space),0,nodes); // put on right
}
}
protected void alignCentersOnLeft(List<Residue> ref_nodes, List<Residue> nodes, int space) throws Exception { alignCentersOnLeft(getAll(ref_nodes), getCurrent(ref_nodes), nodes, space); }
protected void alignCentersOnLeft(Residue ref_node, List<Residue> nodes, int space) throws Exception { alignCentersOnLeft(getAll(ref_node), getCurrent(ref_node), nodes, space); }
protected void alignCentersOnLeft(Rectangle ref_bbox, List<Residue> nodes, int space) throws Exception { alignCentersOnLeft(singleton(ref_bbox), ref_bbox, nodes, space); }
protected void alignCentersOnLeft(Residue ref_node, Residue node, int space) throws Exception { alignCentersOnLeft(getAll(ref_node), getCurrent(ref_node), singleton(node), space); }
protected void alignCentersOnLeft(Rectangle ref_bbox, Residue node, int space) throws Exception { alignCentersOnLeft(singleton(ref_bbox), ref_bbox, singleton(node), space); }
protected void alignCentersOnLeft(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignCentersOnLeft(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
protected void alignCentersOnLeft(List<Residue> ref_sup_nodes, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignCentersOnLeft(new Union<Rectangle>(getAll(ref_sup_nodes)).and(getAll(ref_nodes)),getCurrent(ref_sup_nodes),getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
private void alignCentersOnLeft(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Residue> nodes, int space) throws Exception {
alignCentersOnLeft(ref_all_bboxes,ref_sup_bbox,getAll(nodes),getCurrent(nodes),nodes,space);
}
private void alignCentersOnLeft(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int space) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,space);
translate(0,midy(ref_sup_bbox)-midy(cur_sup_bbox),nodes); // align center
translate(shiftToLeft(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,space),0,nodes); // put on left
}
}
protected void alignCentersOnRight(List<Residue> ref_nodes, List<Residue> nodes, int space) throws Exception { alignCentersOnRight(getAll(ref_nodes), getCurrent(ref_nodes), nodes, space); }
protected void alignCentersOnRight(Residue ref_node, List<Residue> nodes, int space) throws Exception { alignCentersOnRight(getAll(ref_node), getCurrent(ref_node), nodes, space); }
protected void alignCentersOnRight(Rectangle ref_bbox, List<Residue> nodes, int space) throws Exception { alignCentersOnRight(singleton(ref_bbox), ref_bbox, nodes, space); }
protected void alignCentersOnRight(Residue ref_node, Residue node, int space) throws Exception { alignCentersOnRight(getAll(ref_node), getCurrent(ref_node), singleton(node), space); }
protected void alignCentersOnRight(Rectangle ref_bbox, Residue node, int space) throws Exception { alignCentersOnRight(singleton(ref_bbox), ref_bbox, singleton(node), space); }
protected void alignCentersOnRight(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignCentersOnRight(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
protected void alignCentersOnRight(List<Residue> ref_sup_nodes, List<Residue> ref_nodes, List<Residue> sup_nodes, List<Residue> nodes, int space) throws Exception {
alignCentersOnRight(new Union<Rectangle>(getAll(ref_sup_nodes)).and(getAll(ref_nodes)),getCurrent(ref_sup_nodes),getAll(nodes),getCurrent(sup_nodes),nodes,space);
}
private void alignCentersOnRight(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Residue> nodes, int space) throws Exception {
alignCentersOnRight(ref_all_bboxes,ref_sup_bbox,getAll(nodes),getCurrent(nodes),nodes,space);
}
private void alignCentersOnRight(List<Rectangle> ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int space) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,space);
translate(0,midy(ref_sup_bbox)-midy(cur_sup_bbox),nodes); // align center
translate(shiftToRight(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,space),0,nodes); // put on right
}
}
protected void alignCornersOnLeftAtTop(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> nodes, int xspace, int yspace) throws Exception {
alignCornersOnLeftAtTop(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrentComplete(nodes),nodes,xspace,yspace);
}
private void alignCornersOnLeftAtTop(List<Rectangle>ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int xspace, int yspace) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,xspace);
translate(0,top(ref_sup_bbox)-bottom(cur_sup_bbox)-yspace,nodes); // align corner
translate(shiftToLeft(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,xspace),0,nodes); // put on left
}
}
protected void alignCornersOnLeftAtBottom(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> nodes, int xspace, int yspace) throws Exception {
alignCornersOnLeftAtBottom(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrentComplete(nodes),nodes,xspace,yspace);
}
private void alignCornersOnLeftAtBottom(List<Rectangle>ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int xspace, int yspace) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,xspace);
translate(0,bottom(ref_sup_bbox)-top(cur_sup_bbox)+yspace,nodes); // align corner
translate(shiftToLeft(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,xspace),0,nodes); // put on left
}
}
protected void alignCornersOnRightAtTop(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> nodes, int xspace, int yspace) throws Exception {
alignCornersOnRightAtTop(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrentComplete(nodes),nodes,xspace,yspace);
}
private void alignCornersOnRightAtTop(List<Rectangle>ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int xspace, int yspace) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,xspace);
translate(0,top(ref_sup_bbox)-bottom(cur_sup_bbox)-yspace,nodes); // align corner
translate(shiftToRight(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,xspace),0,nodes); // put on right
}
}
protected void alignCornersOnRightAtBottom(Rectangle ref_bbox, List<Residue> ref_nodes, List<Residue> nodes, int xspace, int yspace) throws Exception {
alignCornersOnRightAtBottom(new Union<Rectangle>(ref_bbox).and(getAll(ref_nodes)),ref_bbox,getAll(nodes),getCurrentComplete(nodes),nodes,xspace,yspace);
}
private void alignCornersOnRightAtBottom(List<Rectangle>ref_all_bboxes, Rectangle ref_sup_bbox, List<Rectangle> cur_all_bboxes, Rectangle cur_sup_bbox, List<Residue> nodes, int xspace, int yspace) throws Exception {
if( nodes!=null && nodes.size()>0 ) {
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,nodes,xspace);
translate(0,bottom(ref_sup_bbox)-top(cur_sup_bbox)+yspace,nodes); // align corner
translate(shiftToRight(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,xspace),0,nodes); // put on right
}
}
private int shiftToLeft(List<Rectangle> ref_bboxes, Rectangle ref_bbox, List<Rectangle> cur_bboxes, Rectangle cur_bbox, int space) throws Exception{
return shiftToLeft(ref_bboxes,ref_bbox,cur_bboxes,cur_bbox,space,0);
}
private int shiftToLeft(List<Rectangle> ref_bboxes, Rectangle ref_bbox, List<Rectangle> cur_bboxes, Rectangle cur_bbox, int space, int min_ref_space) throws Exception{
int toll = theGraphicOptions.NODE_SPACE/2-1;
int shift = left(ref_bbox) - Math.max(space,min_ref_space) - right(cur_bbox);
for( Rectangle cur : cur_bboxes )
for( Rectangle ref : ref_bboxes )
if( overlapy(cur,ref,toll) )
shift = Math.min(shift, left(ref) - space - right(cur));
return shift;
}
private int shiftToRight(List<Rectangle> ref_bboxes, Rectangle ref_bbox, List<Rectangle> cur_bboxes, Rectangle cur_bbox, int space) throws Exception{
return shiftToRight(ref_bboxes,ref_bbox,cur_bboxes,cur_bbox,space,0);
}
private int shiftToRight(List<Rectangle> ref_bboxes, Rectangle ref_bbox, List<Rectangle> cur_bboxes, Rectangle cur_bbox, int space, int min_ref_space) throws Exception{
int toll = theGraphicOptions.NODE_SPACE/2-1;
int shift = right(ref_bbox) + Math.max(space,min_ref_space) - left(cur_bbox);
for( Rectangle cur : cur_bboxes )
for( Rectangle ref : ref_bboxes )
if( overlapy(cur,ref,toll) )
shift = Math.max(shift, right(ref) + space - left(cur));
return shift;
}
// SYMMETRIC
protected void alignSymmetricOnLeft(Rectangle ref_sup_bbox, List<Residue> ref_nodes, List<Residue> nodes_t, List<Residue> nodes_b, int space, int min_ref_space) throws Exception {
if( nodes_t!=null && nodes_t.size()>0 && nodes_b!=null && nodes_b.size()>0 ) {
// get bboxes
List<Rectangle> ref_all_bboxes = new Union<Rectangle>(ref_sup_bbox).and(getAll(ref_nodes));
Rectangle cur_sup_bbox_t = getCurrentComplete(nodes_t);
List<Rectangle> cur_all_bboxes_t = getAll(nodes_t);
Rectangle cur_sup_bbox_b = getCurrentComplete(nodes_b);
List<Rectangle> cur_all_bboxes_b = getAll(nodes_b);
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes_t,cur_sup_bbox_t,nodes_t,space);
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes_b,cur_sup_bbox_b,nodes_b,space);
// align cur_t with cur_b
translate(right(cur_sup_bbox_t)-right(cur_sup_bbox_b),0,nodes_b); // align rights
translate(0,shiftToBottom(cur_all_bboxes_t,cur_sup_bbox_t,cur_all_bboxes_b,cur_sup_bbox_b,space,min_ref_space),nodes_b); // put on bottom
// reset bboxes
Union<Residue> nodes = new Union<Residue>(nodes_t).and(nodes_b);
cur_sup_bbox_t = getCurrentComplete(nodes_t);
cur_sup_bbox_b = getCurrentComplete(nodes_b);
Rectangle cur_sup_bbox = union(cur_sup_bbox_t,cur_sup_bbox_b);
List<Rectangle> cur_all_bboxes = getAll(nodes);
// align cur_t and cur_b with ref
translate(0,midy(ref_sup_bbox)-(bottom(cur_sup_bbox_t)+top(cur_sup_bbox_b))/2,nodes); // align symmetric
translate(shiftToLeft(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,space),0,nodes); // put on left
}
}
protected void alignSymmetricOnRight(Rectangle ref_sup_bbox, List<Residue> ref_nodes, List<Residue> nodes_t, List<Residue> nodes_b, int space, int min_ref_space) throws Exception {
if( nodes_t!=null && nodes_t.size()>0 && nodes_b!=null && nodes_b.size()>0 ) {
// get bboxes
List<Rectangle> ref_all_bboxes = new Union<Rectangle>(ref_sup_bbox).and(getAll(ref_nodes));
Rectangle cur_sup_bbox_t = getCurrentComplete(nodes_t);
List<Rectangle> cur_all_bboxes_t = getAll(nodes_t);
Rectangle cur_sup_bbox_b = getCurrentComplete(nodes_b);
List<Rectangle> cur_all_bboxes_b = getAll(nodes_b);
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes_t,cur_sup_bbox_t,nodes_t,space);
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes_b,cur_sup_bbox_b,nodes_b,space);
// align cur_t with cur_b
translate(left(cur_sup_bbox_t)-left(cur_sup_bbox_b),0,nodes_b); // align lefts
translate(0,shiftToBottom(cur_all_bboxes_t,cur_sup_bbox_t,cur_all_bboxes_b,cur_sup_bbox_b,space,min_ref_space),nodes_b); // put on bottom
// reset bboxes
Union<Residue> nodes = new Union<Residue>(nodes_t).and(nodes_b);
cur_sup_bbox_t = getCurrentComplete(nodes_t);
cur_sup_bbox_b = getCurrentComplete(nodes_b);
Rectangle cur_sup_bbox = union(cur_sup_bbox_t,cur_sup_bbox_b);
List<Rectangle> cur_all_bboxes = getAll(nodes);
// align cur_t and cur_b with ref
translate(0,midy(ref_sup_bbox)-(bottom(cur_sup_bbox_t)+top(cur_sup_bbox_b))/2,nodes); // align symmetric
translate(shiftToRight(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,space),0,nodes); // put on right
}
}
protected void alignSymmetricOnBottom(Rectangle ref_sup_bbox, List<Residue> ref_nodes, List<Residue> nodes_l, List<Residue> nodes_r, int space, int min_ref_space) throws Exception {
if( nodes_l!=null && nodes_l.size()>0 && nodes_r!=null && nodes_r.size()>0 ) {
// get bboxes
List<Rectangle> ref_all_bboxes = new Union<Rectangle>(ref_sup_bbox).and(getAll(ref_nodes));
Rectangle cur_sup_bbox_l = getCurrentComplete(nodes_l);
List<Rectangle> cur_all_bboxes_l = getAll(nodes_l);
Rectangle cur_sup_bbox_r = getCurrentComplete(nodes_r);
List<Rectangle> cur_all_bboxes_r = getAll(nodes_r);
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes_l,cur_sup_bbox_l,nodes_l,space);
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes_r,cur_sup_bbox_r,nodes_r,space);
// align cur_l with cur_r
translate(top(cur_sup_bbox_l)-top(cur_sup_bbox_r),0,nodes_r); // align tops
translate(shiftToRight(cur_all_bboxes_l,cur_sup_bbox_l,cur_all_bboxes_r,cur_sup_bbox_r,space,min_ref_space),0,nodes_r); // put on right
// reset bboxes
Union<Residue> nodes = new Union<Residue>(nodes_l).and(nodes_r);
cur_sup_bbox_l = getCurrentComplete(nodes_l);
cur_sup_bbox_r = getCurrentComplete(nodes_r);
Rectangle cur_sup_bbox = union(cur_sup_bbox_l,cur_sup_bbox_r);
List<Rectangle> cur_all_bboxes = getAll(nodes);
// align cur_l and cur_r with ref
translate(midx(ref_sup_bbox)-(right(cur_sup_bbox_l)+left(cur_sup_bbox_r))/2,0,nodes); // align symmetric
translate(0,shiftToBottom(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,space),nodes); // put on bottom
}
}
protected void alignSymmetricOnTop(Rectangle ref_sup_bbox, List<Residue> ref_nodes, List<Residue> nodes_l, List<Residue> nodes_r, int space, int min_ref_space) throws Exception {
if( nodes_l!=null && nodes_l.size()>0 && nodes_r!=null && nodes_r.size()>0 ) {
// get bboxes
List<Rectangle> ref_all_bboxes = new Union<Rectangle>(ref_sup_bbox).and(getAll(ref_nodes));
Rectangle cur_sup_bbox_l = getCurrentComplete(nodes_l);
List<Rectangle> cur_all_bboxes_l = getAll(nodes_l);
Rectangle cur_sup_bbox_r = getCurrentComplete(nodes_r);
List<Rectangle> cur_all_bboxes_r = getAll(nodes_r);
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes_l,cur_sup_bbox_l,nodes_l,space);
assertAlignment(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes_r,cur_sup_bbox_r,nodes_r,space);
// align cur_l with cur_r
translate(bottom(cur_sup_bbox_l)-bottom(cur_sup_bbox_r),0,nodes_r); // align bottoms
translate(shiftToRight(cur_all_bboxes_l,cur_sup_bbox_l,cur_all_bboxes_r,cur_sup_bbox_r,space,min_ref_space),0,nodes_r); // put on right
// reset bboxes
Union<Residue> nodes = new Union<Residue>(nodes_l).and(nodes_r);
cur_sup_bbox_l = getCurrentComplete(nodes_l);
cur_sup_bbox_r = getCurrentComplete(nodes_r);
Rectangle cur_sup_bbox = union(cur_sup_bbox_l,cur_sup_bbox_r);
List<Rectangle> cur_all_bboxes = getAll(nodes);
// align cur_l and cur_r with ref
translate(midx(ref_sup_bbox)-(right(cur_sup_bbox_l)+left(cur_sup_bbox_r))/2,0,nodes); // align symmetric
translate(0,shiftToTop(ref_all_bboxes,ref_sup_bbox,cur_all_bboxes,cur_sup_bbox,space),nodes); // put on top
}
}
}