X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=srcjar%2Ffr%2Forsay%2Flri%2Fvarna%2Fapplications%2FtemplateEditor%2FHelix.java;fp=srcjar%2Ffr%2Forsay%2Flri%2Fvarna%2Fapplications%2FtemplateEditor%2FHelix.java;h=4c81bed1ec482a2d2beeb17ea32c5b4b9c143e0d;hb=4f30214e8098748469c6a4269ac2ed6c5750e4b0;hp=0000000000000000000000000000000000000000;hpb=9dabc02511e3a334a5749a504f57f69d6c9017bd;p=jalview.git diff --git a/srcjar/fr/orsay/lri/varna/applications/templateEditor/Helix.java b/srcjar/fr/orsay/lri/varna/applications/templateEditor/Helix.java new file mode 100644 index 0000000..4c81bed --- /dev/null +++ b/srcjar/fr/orsay/lri/varna/applications/templateEditor/Helix.java @@ -0,0 +1,687 @@ +package fr.orsay.lri.varna.applications.templateEditor; + +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.awt.Shape; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import fr.orsay.lri.varna.exceptions.ExceptionInvalidRNATemplate; +import fr.orsay.lri.varna.models.rna.RNA; +import fr.orsay.lri.varna.models.templates.RNATemplate; +import fr.orsay.lri.varna.models.templates.RNATemplate.EdgeEndPointPosition; +import fr.orsay.lri.varna.models.templates.RNATemplate.RNATemplateHelix; +import fr.orsay.lri.varna.models.templates.RNATemplate.RNATemplateElement.EdgeEndPoint; + + +public class Helix extends GraphicalTemplateElement{ + + RNATemplateHelix _h; + + public Helix(double x, double y, RNATemplate tmp, List existingRNAElements) + { + this(x,y,getNextAutomaticCaption(existingRNAElements),tmp); + } + + public Helix(double x, double y, String cap, RNATemplate tmp) + { + _h = tmp.new RNATemplateHelix(cap); + _h.setStartPosition(new Point2D.Double(x,y)); + _h.setEndPosition(new Point2D.Double(x,y)); + _h.setLength(1); + _h.setCaption(cap); + } + + public Helix(RNATemplateHelix templateHelix) { + _h = templateHelix; + } + + + private static String getNextAutomaticCaption(List existingRNAElements) { + // Find which captions are already used + Set captions = new HashSet(); + for (GraphicalTemplateElement element: existingRNAElements) { + if (element instanceof Helix) { + Helix helix = (Helix) element; + if (helix.getCaption() != null) { + captions.add(helix.getCaption()); + } + } + } + // Find a non-conflicting name for this helix + for (int i=1;;i++) { + String candidateCaption = "H" + i; + if (! captions.contains(candidateCaption)) { + return candidateCaption; + } + } + } + + public void toggleFlipped() + { + _h.setFlipped(!_h.isFlipped()); + updateAttachedUnpairedRegions(); + } + + + /** + * When an helix is moved/resized/etc... it is necessary to update + * the positions of endpoints from unpaired regions that are attached + * to the helix. This function updates the endpoints positions of + * attached unpaired regions. + */ + public void updateAttachedUnpairedRegions() { + for (RelativePosition rpos: getConnectedEdges()) { + Couple c = getAttachedElement(rpos); + if (c != null && c.second instanceof UnpairedRegion) { + UnpairedRegion unpairedRegion = (UnpairedRegion) c.second; + Point2D.Double pos = getEdgePosition(rpos); + if (c.first == RelativePosition.RP_CONNECT_START5) { + unpairedRegion.setEdge5(pos); + } else if (c.first == RelativePosition.RP_CONNECT_END3) { + unpairedRegion.setEdge3(pos); + } + } + } + } + + public double getPosX() + { + return _h.getStartPosition().x; + } + + public String getCaption() + { + return _h.getCaption(); + } + + public double getPosY() + { + return _h.getStartPosition().y; + } + + public RNATemplateHelix getTemplateElement() + { + return _h; + } + + public void setX(double x) + { + _h.getStartPosition().x = x; + } + + public void setY(double y) + { + _h.getStartPosition().y = y; + } + + public void setPos(Point2D.Double p) + { + _h.setStartPosition(p); + updateLength(); + } + + public void setPos(double x, double y) + { + setPos(new Point2D.Double(x,y)); + } + + public Point2D.Double getPos() + { + return _h.getStartPosition(); + } + + public void moveCenter(double x, double y) + { + Point2D.Double center = new Point2D.Double((_h.getStartPosition().x+_h.getEndPosition().x)/2.0,(_h.getStartPosition().y+_h.getEndPosition().y)/2.0); + double dx = x-center.x; + double dy = y-center.y; + _h.setStartPosition(new Point2D.Double(_h.getStartPosition().x+dx,_h.getStartPosition().y+dy)); + _h.setEndPosition(new Point2D.Double(_h.getEndPosition().x+dx,_h.getEndPosition().y+dy)); + } + + + public void setExtent(double x, double y) + { + setExtent(new Point2D.Double(x,y)); + } + + private void updateLength() + { + _h.setLength(getNbBP()); + } + + public void setExtent(Point2D.Double p) + { + _h.setEndPosition(p); + updateLength(); + } + + public double getExtentX() + { + return _h.getEndPosition().x; + } + + public Point2D.Double getExtent() + { + return _h.getEndPosition(); + } + + public double getExtentY() + { + return _h.getEndPosition().y; + } + + public static final double BASE_PAIR_DISTANCE = RNA.BASE_PAIR_DISTANCE; + public static final double LOOP_DISTANCE = RNA.LOOP_DISTANCE; + public static final double SELECTION_RADIUS = 15.0; + + + + + public Point2D.Double getAbsStart5() + { + double dx = (_h.getStartPosition().x-_h.getEndPosition().x)/(_h.getStartPosition().distance(_h.getEndPosition())); + double dy = (_h.getStartPosition().y-_h.getEndPosition().y)/(_h.getStartPosition().distance(_h.getEndPosition())); + double nx = dy; + double ny = -dx; + Point2D.Double start5 = new Point2D.Double((getPosX()-Helix.BASE_PAIR_DISTANCE*nx/2.0),(getPosY()-Helix.BASE_PAIR_DISTANCE*ny/2.0)); + return start5; + } + + public Point2D.Double getAbsStart3() + { + double dx = (_h.getStartPosition().x-_h.getEndPosition().x)/(_h.getStartPosition().distance(_h.getEndPosition())); + double dy = (_h.getStartPosition().y-_h.getEndPosition().y)/(_h.getStartPosition().distance(_h.getEndPosition())); + double nx = dy; + double ny = -dx; + Point2D.Double start3 = new Point2D.Double((getPosX()+Helix.BASE_PAIR_DISTANCE*nx/2.0),(getPosY()+Helix.BASE_PAIR_DISTANCE*ny/2.0)); + return start3; + } + + public Point2D.Double getAbsEnd5() + { + double dx = (_h.getStartPosition().x-_h.getEndPosition().x)/(_h.getStartPosition().distance(_h.getEndPosition())); + double dy = (_h.getStartPosition().y-_h.getEndPosition().y)/(_h.getStartPosition().distance(_h.getEndPosition())); + double nx = dy; + double ny = -dx; + Point2D.Double end5 = new Point2D.Double((getExtentX()-Helix.BASE_PAIR_DISTANCE*nx/2.0),(getExtentY()-Helix.BASE_PAIR_DISTANCE*ny/2.0)); + return end5; + } + + public Point2D.Double getAbsEnd3() + { + double dx = (_h.getStartPosition().x-_h.getEndPosition().x)/(_h.getStartPosition().distance(_h.getEndPosition())); + double dy = (_h.getStartPosition().y-_h.getEndPosition().y)/(_h.getStartPosition().distance(_h.getEndPosition())); + double nx = dy; + double ny = -dx; + Point2D.Double end3 = new Point2D.Double((getExtentX()+Helix.BASE_PAIR_DISTANCE*nx/2.0),(getExtentY()+Helix.BASE_PAIR_DISTANCE*ny/2.0)); + return end3; + } + + public Point2D.Double getStart5() + { + if (_h.isFlipped()) + return getAbsStart3(); + else + return getAbsStart5(); + + } + + public Point2D.Double getStart3() + { + if (_h.isFlipped()) + return getAbsStart5(); + else + return getAbsStart3(); + } + + public Point2D.Double getEnd5() + { + if (_h.isFlipped()) + return getAbsEnd3(); + else + return getAbsEnd5(); + } + + public Point2D.Double getEnd3() + { + if (_h.isFlipped()) + return getAbsEnd5(); + else + return getAbsEnd3(); + } + + public Polygon getBoundingPolygon() + { + double dx = (_h.getStartPosition().x-_h.getEndPosition().x)/(_h.getStartPosition().distance(_h.getEndPosition())); + double dy = (_h.getStartPosition().y-_h.getEndPosition().y)/(_h.getStartPosition().distance(_h.getEndPosition())); + double nx = dy; + double ny = -dx; + Point2D.Double start5 = new Point2D.Double((getPosX()+Helix.BASE_PAIR_DISTANCE*nx/2.0),(getPosY()+Helix.BASE_PAIR_DISTANCE*ny/2.0)); + Point2D.Double end5 = new Point2D.Double((getExtentX()+Helix.BASE_PAIR_DISTANCE*nx/2.0),(getExtentY()+Helix.BASE_PAIR_DISTANCE*ny/2.0)); + Point2D.Double start3 = new Point2D.Double((getPosX()-Helix.BASE_PAIR_DISTANCE*nx/2.0),(getPosY()-Helix.BASE_PAIR_DISTANCE*ny/2.0)); + Point2D.Double end3 = new Point2D.Double((getExtentX()-Helix.BASE_PAIR_DISTANCE*nx/2.0),(getExtentY()-Helix.BASE_PAIR_DISTANCE*ny/2.0)); + Polygon p = new Polygon(); + p.addPoint((int)start5.x, (int)start5.y); + p.addPoint((int)end5.x, (int)end5.y); + p.addPoint((int)end3.x, (int)end3.y); + p.addPoint((int)start3.x, (int)start3.y); + return p; + } + + + public Point2D.Double getCenter() + { + return new Point2D.Double((int)((_h.getStartPosition().x+_h.getEndPosition().x)/2.0), + (int)((_h.getStartPosition().y+_h.getEndPosition().y)/2.0)); + } + + + public Point2D.Double getCenterEditStart() + { + double dist = _h.getStartPosition().distance(_h.getEndPosition()); + double dx = (_h.getEndPosition().x-_h.getStartPosition().x)/(dist); + double dy = (_h.getEndPosition().y-_h.getStartPosition().y)/(dist); + return new Point2D.Double((int)(_h.getStartPosition().x+(dist-10.0)*dx), + (int)(_h.getStartPosition().y+(dist-10.0)*dy)); + } + + public Point2D.Double getCenterEditEnd() + { + double dist = _h.getStartPosition().distance(_h.getEndPosition()); + double dx = (_h.getEndPosition().x-_h.getStartPosition().x)/(dist); + double dy = (_h.getEndPosition().y-_h.getStartPosition().y)/(dist); + return new Point2D.Double((int)(_h.getStartPosition().x+(10.0)*dx), + (int)(_h.getStartPosition().y+(10.0)*dy)); + } + + + public Shape getSelectionBox() + { + double dx = (_h.getStartPosition().x-_h.getEndPosition().x)/(_h.getStartPosition().distance(_h.getEndPosition())); + double dy = (_h.getStartPosition().y-_h.getEndPosition().y)/(_h.getStartPosition().distance(_h.getEndPosition())); + double nx = dy; + double ny = -dx; + Polygon hbox = getBoundingPolygon(); + Polygon p = new Polygon(); + Point2D.Double start5 = new Point2D.Double(hbox.xpoints[0]+SELECTION_RADIUS*(dx+nx),hbox.ypoints[0]+SELECTION_RADIUS*(dy+ny)); + Point2D.Double end5 = new Point2D.Double(hbox.xpoints[1]+SELECTION_RADIUS*(-dx+nx),hbox.ypoints[1]+SELECTION_RADIUS*(-dy+ny)); + Point2D.Double end3 = new Point2D.Double(hbox.xpoints[2]+SELECTION_RADIUS*(-dx-nx),hbox.ypoints[2]+SELECTION_RADIUS*(-dy-ny));; + Point2D.Double start3 = new Point2D.Double(hbox.xpoints[3]+SELECTION_RADIUS*(dx-nx),hbox.ypoints[3]+SELECTION_RADIUS*(dy-ny));; + p.addPoint((int)start5.x, (int)start5.y); + p.addPoint((int)end5.x, (int)end5.y); + p.addPoint((int)end3.x, (int)end3.y); + p.addPoint((int)start3.x, (int)start3.y); + return p; + } + + public Shape getArea() + { + return getSelectionBox(); + } + + + public static final double EDIT_RADIUS = 10.0; + public static final double MOVE_RADIUS = 13.0; + public static final double BASE_RADIUS = 8.0; + public static final double EDGE_BASE_RADIUS = 7.0; + + + public RelativePosition getRelativePosition(double x, double y) + { + Point2D.Double current = new Point2D.Double(x,y); + Shape p = getSelectionBox(); + if (p.contains(current)) + { + if (getCenterEditStart().distance(current) getConnectedEdges() { + ArrayList result = new ArrayList(); + result.add(RelativePosition.RP_CONNECT_START5); + result.add(RelativePosition.RP_CONNECT_START3); + result.add(RelativePosition.RP_CONNECT_END5); + result.add(RelativePosition.RP_CONNECT_END3); + return result; + } + + public String toString() + { + return "Helix " + getCaption(); + } + + public RelativePosition relativePositionFromEdgeEndPointPosition( + EdgeEndPointPosition pos) { + switch (pos) { + case IN1: + return RelativePosition.RP_CONNECT_START5; + case OUT1: + return RelativePosition.RP_CONNECT_END5; + case IN2: + return RelativePosition.RP_CONNECT_END3; + case OUT2: + return RelativePosition.RP_CONNECT_START3; + default: + return null; + } + } + +} +