package fr.orsay.lri.varna.models.rna;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Random;
import java.util.Stack;
import java.util.Vector;
import fr.orsay.lri.varna.VARNAPanel;
public class VARNASecDraw {
public static VARNAPanel _vp = null;
public abstract class Portion
{
public abstract ArrayList<Integer> getBaseList();
public abstract int getNumBases();
public abstract GeneralPath getOutline(RNA r);
};
public class UnpairedPortion extends Portion
{
int _pos;
int _len;
public UnpairedPortion(int pos, int len)
{
_len = len;
_pos = pos;
}
@Override
public ArrayList<Integer> getBaseList() {
// TODO Auto-generated method stub
return null;
}
public String toString()
{
return "U["+_pos+","+(_pos+_len-1)+"]";
}
public int getNumBases() {
return _len;
}
public GeneralPath getOutline(RNA r) {
GeneralPath gp = new GeneralPath();
ArrayList<ModeleBase> l = r.get_listeBases();
Point2D.Double p0 = l.get(_pos).getCoords();
gp.moveTo((float)p0.x, (float)p0.y);
for (int i=1;i<_len;i++)
{
Point2D.Double p = l.get(_pos+i).getCoords();
gp.lineTo((float)p.x, (float)p.y);
}
return gp;
}
};
public class PairedPortion extends Portion
{
int _pos1;
int _pos2;
int _len;
RNATree _r;
public PairedPortion(int pos1,int pos2, int len, RNATree r)
{
_pos1 = pos1;
_pos2 = pos2;
_len = len;
_r =r;
}
@Override
public ArrayList<Integer> getBaseList() {
// TODO Auto-generated method stub
return null;
}
public String toString()
{
return "H["+_pos1+","+(_pos1+_len-1)+"]["+(_pos2-_len+1)+","+(_pos2)+"]\n"+_r.toString();
}
@Override
public int getNumBases() {
return 2*_len;
}
public GeneralPath getLocalOutline(RNA r) {
GeneralPath gp = new GeneralPath();
if (_len>0)
{
ArrayList<ModeleBase> l = r.get_listeBases();
Point2D.Double p1 = l.get(_pos1).getCoords();
Point2D.Double p2 = l.get(_pos1+_len-1).getCoords();
Point2D.Double p3 = l.get(_pos2-_len+1).getCoords();
Point2D.Double p4 = l.get(_pos2).getCoords();
gp.moveTo((float)p1.x, (float)p1.y);
gp.lineTo((float)p2.x, (float)p2.y);
gp.lineTo((float)p3.x, (float)p3.y);
gp.lineTo((float)p4.x, (float)p4.y);
}
return gp;
}
public GeneralPath getOutline(RNA r) {
return getOutline(r,false);
}
public GeneralPath getOutline(RNA r, boolean local) {
ArrayList<ModeleBase> l = r.get_listeBases();
Point2D.Double p1 = l.get(_pos1).getCoords();
Point2D.Double p2 = l.get(_pos1+_len-1).getCoords();
Point2D.Double p3 = l.get(_pos2-_len+1).getCoords();
Point2D.Double p4 = l.get(_pos2).getCoords();
GeneralPath gp = new GeneralPath();
gp.moveTo((float)p1.x, (float)p1.y);
gp.lineTo((float)p2.x, (float)p2.y);
if (!local)
gp.append(_r.getOutline(r), true);
gp.lineTo((float)p3.x, (float)p3.y);
gp.lineTo((float)p4.x, (float)p4.y);
return gp;
}
};
public int _depth = 0;
public class RNATree
{
ArrayList<Portion> _portions = new ArrayList<Portion>();
int _numPairedPortions=0;
public RNATree()
{
}
public void addPortion(Portion p)
{
_portions.add(p);
if (p instanceof PairedPortion)
{
_numPairedPortions++;
}
}
public int getNumPortions()
{
return _portions.size();
}
public Portion getPortion(int i)
{
return _portions.get(i);
}
public String toString()
{
String result = "";
_depth++;
for (int i=0;i<_portions.size();i++ )
{
result += String.format("%1$#" + _depth + "s", ' ');
result += _portions.get(i).toString();
if (i<_portions.size()-1)
result += "\n";
}
_depth--;
return result;
}
public GeneralPath getOutline(RNA r) {
GeneralPath result = new GeneralPath();
for (int i=0;i<_portions.size();i++)
{
result.append(_portions.get(i).getOutline(r),true);
}
return result;
}
};
private void buildTree(int i, int j, RNATree parent, RNA r)
{
//LinkedList<BuildTreeArgs> s = new LinkedList<BuildTreeArgs>();
//s.add(new BuildTreeArgs(xi, xj, xparent,xr));
//while(s.size()!=0)
//{
//BuildTreeArgs a = s.removeLast();
if (i >= j) {
parent.addPortion(new UnpairedPortion(i,j-i+1));
}
// BasePaired
if (r.get_listeBases().get(i).getElementStructure() == j)
{
int i1 = i;
int j1 = j;
boolean over = false;
while( (i+1<r.get_listeBases().size()) && (j-1>=0)&& (i+1<=j-1) && !over)
{
if (r.get_listeBases().get(i).getElementStructure() != j)
{ over = true; }
else
{ i++;j--; }
}
int i2 = i;
int j2 = j;
RNATree t = new RNATree();
if (i<j-1)
buildTree(i2,j2,t,r);
PairedPortion p = new PairedPortion(i1,j1,i2-i1,t);
parent.addPortion(p);
} else
{
int k = i;
int l;
int start = k;
int len = 0;
while (k <= j) {
l = r.get_listeBases().get(k).getElementStructure();
if (l != -1)
{
if (len>0)
{ parent.addPortion(new UnpairedPortion(start,len)); }
buildTree(k, l, parent, r);
k = l + 1;
start = k;
len = 0;
} else {
len++;
k++;
}
}
if (len>0)
{
parent.addPortion(new UnpairedPortion(start,len));
}
}
}
/*
public void drawTree(double x0, double y0, RNATree t, double dir, RNA r, double straightness)
{
boolean collision = true;
double x=x0;
double y=y0;
double multRadius = 1.0;
double initCirc = r.BASE_PAIR_DISTANCE+r.LOOP_DISTANCE;
for (int i=0;i<t.getNumPortions();i++ )
{
Portion p = t.getPortion(i);
if (p instanceof PairedPortion)
{
initCirc += (r.BASE_PAIR_DISTANCE+r.LOOP_DISTANCE);
}
else
{
initCirc += r.LOOP_DISTANCE*(p.getNumBases());
}
}
while(collision)
{
double totCirc = r.BASE_PAIR_DISTANCE+straightness*r.LOOP_DISTANCE;
for (int i=0;i<t.getNumPortions();i++ )
{
Portion p = t.getPortion(i);
if (p instanceof PairedPortion)
{
totCirc += (r.BASE_PAIR_DISTANCE+r.LOOP_DISTANCE);
}
else
{
double mod = 1.0;
if ((i==0) || (i==t.getNumPortions()-1))
mod = straightness;
totCirc += mod*r.LOOP_DISTANCE*(p.getNumBases());
}
}
double radius = multRadius*initCirc/(2.0*Math.PI);
//radius = 2.0;
x = x0+radius*Math.cos(dir+Math.PI);
y = y0+radius*Math.sin(dir+Math.PI);
dir += 2.0*Math.PI;
double angleIncr = (2.0*Math.PI)/(totCirc);
double circ = r.BASE_PAIR_DISTANCE/2.0+straightness*r.LOOP_DISTANCE;
double ndir;
ArrayList<GeneralPath> shapes = new ArrayList<GeneralPath>();
for (int i=0;i<t.getNumPortions();i++ )
{
Portion p = t.getPortion(i);
if (p instanceof PairedPortion)
{
circ+=r.BASE_PAIR_DISTANCE/2.0;
ndir = dir + circ*angleIncr;
PairedPortion pp = (PairedPortion) p;
for(int j=0;j<pp._len;j++)
{
int i1 = pp._pos1+j;
int i2 = pp._pos2-j;
double vx = Math.cos(ndir);
double vy = Math.sin(ndir);
double nx = x+((j*r.LOOP_DISTANCE+radius)*vx);
double ny = y+((j*r.LOOP_DISTANCE+radius)*vy);
r.get_listeBases().get(i1).set_coords(new Point2D.Double(nx+r.BASE_PAIR_DISTANCE*vy/ 2.0,ny-r.BASE_PAIR_DISTANCE*vx/ 2.0));
r.get_listeBases().get(i2).set_coords(new Point2D.Double(nx-r.BASE_PAIR_DISTANCE*vy/ 2.0,ny+r.BASE_PAIR_DISTANCE*vx/ 2.0));
}
double nx = x+(((pp._len-1)*r.LOOP_DISTANCE+radius)*Math.cos(ndir));
double ny = y+(((pp._len-1)*r.LOOP_DISTANCE+radius)*Math.sin(ndir));
drawTree(nx, ny, pp._r, ndir+Math.PI, r, straightness);
shapes.add(pp.getOutline(r));
circ += r.LOOP_DISTANCE + r.BASE_PAIR_DISTANCE/2.0;
}
else if (p instanceof UnpairedPortion)
{
UnpairedPortion up = (UnpairedPortion) p;
double mod = 1.0;
if ((i==0) || (i==t.getNumPortions()-1))
mod = straightness;
for(int j=0;j<up._len;j++)
{
ndir = dir + circ*angleIncr;
double vx = Math.cos(ndir);
double vy = Math.sin(ndir);
double nx = x+((radius)*vx);
double ny = y+((radius)*vy);
r.get_listeBases().get(up._pos+j).set_coords(new Point2D.Double(nx,ny));
circ += mod*r.LOOP_DISTANCE;
}
}
//System.out.println(dir);
}
circ += r.BASE_PAIR_DISTANCE/2.0;
System.out.println(""+circ+"/"+totCirc);
if(shapes.size()>0)
{
collision = false;
for (int i=0;(i<shapes.size()) && !collision;i++)
{
Area a1 = new Area(shapes.get(i));
for (int j=i+1;(j<shapes.size())&& !collision;j++)
{
Area a2 = new Area(shapes.get(j));
a1.intersect(a2);
if (!a1.isEmpty())
{
collision = true;
}
}
}
if (collision)
{
straightness *= 1.2;
multRadius *= 1.5;
}
}
else
{
collision = false;
}
}
}
*/
public int[] nextPlacement(int[] p) throws Exception
{
//System.out.println(Arrays.toString(p));
int i=p.length-1;
int prev = MAX_NUM_DIR;
boolean stop = false;
while((i>=0) && !stop)
{
if (p[i]==prev-1)
{
prev = p[i];
i--;
}
else
{ stop = true; }
}
if (i<0)
throw new Exception("No more placement available");
p[i]++;
i++;
while(i<p.length)
{
p[i] = p[i-1]+1;
i++;
}
//System.out.println(Arrays.toString(p));
return p;
}
public void drawTree(double x0, double y0, RNATree t, double dir, RNA r) throws Exception
{
boolean collision = true;
double x=x0;
double y=y0;
int numHelices = 0;
int nbHel = 1;
int nbUn = 0;
double totCirc = r.BASE_PAIR_DISTANCE+r.LOOP_DISTANCE;
for (int i=0;i<t.getNumPortions();i++ )
{
Portion p = t.getPortion(i);
if (p instanceof PairedPortion)
{
totCirc += (r.BASE_PAIR_DISTANCE+r.LOOP_DISTANCE);
nbHel += 1;
}
else
{
totCirc += r.LOOP_DISTANCE*(p.getNumBases());
nbUn += p.getNumBases()+1;
}
}
double radius = r.determineRadius(nbHel, nbUn, totCirc/(2.0*Math.PI));
for (int i=0;i<t.getNumPortions();i++ )
{
Portion p = t.getPortion(i);
if (p instanceof PairedPortion)
{
numHelices++;
}
}
int[] placement = new int[numHelices];
double inc = ((double)MAX_NUM_DIR)/((double)numHelices+1);
double val = inc;
for (int i=0;i<numHelices;i++ )
{
placement[i] = (int)Math.round(val);
val += inc;
}
System.out.println();
double angleIncr = 2.0*Math.PI/(double)MAX_NUM_DIR;
while(collision)
{
x = x0+radius*Math.cos(dir+Math.PI);
y = y0+radius*Math.sin(dir+Math.PI);
ArrayList<GeneralPath> shapes = new ArrayList<GeneralPath>();
int curH = 0;
for (int i=0;i<t.getNumPortions();i++ )
{
Portion p = t.getPortion(i);
if (p instanceof PairedPortion)
{
double ndir = dir + placement[curH]*angleIncr;
curH++;
PairedPortion pp = (PairedPortion) p;
for(int j=0;j<pp._len;j++)
{
int i1 = pp._pos1+j;
int i2 = pp._pos2-j;
double vx = Math.cos(ndir);
double vy = Math.sin(ndir);
double nx = x+(((j)*r.LOOP_DISTANCE+radius)*vx);
double ny = y+(((j)*r.LOOP_DISTANCE+radius)*vy);
r.get_listeBases().get(i1).setCoords(new Point2D.Double(nx+r.BASE_PAIR_DISTANCE*vy/ 2.0,ny-r.BASE_PAIR_DISTANCE*vx/ 2.0));
r.get_listeBases().get(i2).setCoords(new Point2D.Double(nx-r.BASE_PAIR_DISTANCE*vy/ 2.0,ny+r.BASE_PAIR_DISTANCE*vx/ 2.0));
}
double nx = x+(((pp._len-1)*r.LOOP_DISTANCE+radius)*Math.cos(ndir));
double ny = y+(((pp._len-1)*r.LOOP_DISTANCE+radius)*Math.sin(ndir));
drawTree(nx, ny, pp._r, ndir+Math.PI, r);
shapes.add(pp.getOutline(r));
}
else if (p instanceof UnpairedPortion)
{
UnpairedPortion up = (UnpairedPortion) p;
for(int j=0;j<up._len;j++)
{
/*ndir = dir + circ*angleIncr;
double vx = Math.cos(ndir);
double vy = Math.sin(ndir);
double nx = x+((radius)*vx);
double ny = y+((radius)*vy);
r.get_listeBases().get(up._pos+j).set_coords(new Point2D.Double(nx,ny));
circ += mod*r.LOOP_DISTANCE;*/
r.get_listeBases().get(up._pos+j).setCoords(new Point2D.Double(x,y));
}
}
//System.out.println(dir);
}
if(shapes.size()>0)
{
collision = false;
for (int i=0;(i<shapes.size()) && !collision;i++)
{
Area a1 = new Area(shapes.get(i));
for (int j=i+1;(j<shapes.size())&& !collision;j++)
{
Area a2 = new Area(shapes.get(j));
a1.intersect(a2);
if (!a1.isEmpty())
{
collision = true;
}
}
}
if (collision)
{
placement = nextPlacement(placement);
}
}
else
{
collision = false;
}
}
}
private class HelixEmbedding
{
private GeneralPath _clip;
Point2D.Double _support;
ArrayList<HelixEmbedding> _children = new ArrayList<HelixEmbedding>();
ArrayList<Integer> _indices = new ArrayList<Integer>();
PairedPortion _p;
RNA _r;
HelixEmbedding _parent;
public HelixEmbedding(Point2D.Double support, PairedPortion p, RNA r, HelixEmbedding parent)
{
_support = support;
_clip = p.getLocalOutline(r);
_p = p;
_r = r;
_parent = parent;
}
public void addHelixEmbedding(HelixEmbedding h, int index)
{
_children.add(h);
_indices.add(index);
}
public GeneralPath getShape()
{
return _clip;
}
public int chooseNextMove()
{
int i = _parent._children.indexOf(this);
int min;
int max;
if (_parent._children.size()<VARNASecDraw.MAX_NUM_DIR-1)
{
if (_parent._children.size()==1)
{ min=1;max=VARNASecDraw.MAX_NUM_DIR-1; }
else
{
if (i==0)
{ min = 1; }
else
{ min = _parent._indices.get(i-1)+1;}
if (i==_parent._children.size()-1)
{ max = VARNASecDraw.MAX_NUM_DIR-1; }
else
{ max = _parent._indices.get(i+1)-1;}
}
int prevIndex = _parent._indices.get(i);
int newIndex = min+_rnd.nextInt(max+1-min);
double rot = ((double)(newIndex-prevIndex)*Math.PI*2.0)/MAX_NUM_DIR;
_parent._indices.set(i, newIndex);
rotate(rot);
return newIndex-prevIndex;
}
return 0;
}
public void cancelMove(int delta)
{
int i = _parent._children.indexOf(this);
int prevIndex = _parent._indices.get(i);
double rot = ((double)(-delta)*Math.PI*2.0)/MAX_NUM_DIR;
_parent._indices.set(i, prevIndex-delta);
rotate(rot);
}
public void rotate(double angle)
{
transform(AffineTransform.getRotateInstance(angle, _support.x, _support.y));
}
private void transform(AffineTransform a)
{
_clip.transform(a);
Point2D p = a.transform(_support, null);
_support.setLocation(p.getX(), p.getY());
for (int i=0;i<_children.size();i++)
{
_children.get(i).transform(a);
}
}
public void reflectCoordinates()
{
ArrayList<ModeleBase> mbl = _r.get_listeBases();
if (_p._len>0)
{
PathIterator pi = _clip.getPathIterator(AffineTransform.getRotateInstance(0.0));
ArrayList<Point2D.Double> p = new ArrayList<Point2D.Double>();
while(!pi.isDone())
{
double[] args = new double[6];
int type= pi.currentSegment(args);
if ((type == PathIterator.SEG_MOVETO) || (type == PathIterator.SEG_LINETO))
{
Point2D.Double np = new Point2D.Double(args[0],args[1]);
p.add(np);
System.out.println(Arrays.toString(args));
}
pi.next();
}
if (p.size()<4)
{ return; }
Point2D.Double startLeft = p.get(0);
Point2D.Double endLeft = p.get(1);
Point2D.Double endRight = p.get(2);
Point2D.Double startRight = p.get(3);
double d = startLeft.distance(endLeft);
double vx = endLeft.x-startLeft.x;
double vy = endLeft.y-startLeft.y;
double interval = 0.0;
if (_p._len>1)
{
vx/=d;
vy/=d;
interval = d/((double)_p._len-1);
System.out.println("DELTA: "+interval+" "+_r.LOOP_DISTANCE);
}
for (int n=0;n<_p._len;n++)
{
int i = _p._pos1 + n;
int j = _p._pos2 - n;
ModeleBase mbLeft = mbl.get(i);
mbLeft.setCoords(new Point2D.Double(startLeft.x+n*vx*interval, startLeft.y+n*vy*interval));
ModeleBase mbRight = mbl.get(j);
mbRight.setCoords(new Point2D.Double(startRight.x+n*vx*interval, startRight.y+n*vy*interval));
}
}
for (int i=0;i<_children.size();i++)
{
_children.get(i).reflectCoordinates();
}
if (_children.size()>0)
{
Point2D.Double center = _children.get(0)._support;
for (int i=0;i<_p._r.getNumPortions();i++)
{
Portion p = _p._r.getPortion(i);
if (p instanceof UnpairedPortion)
{
UnpairedPortion up = (UnpairedPortion) p;
for (int j=0;j<up._len;j++)
{
int n = up._pos + j;
ModeleBase mbLeft = mbl.get(n);
mbLeft.setCoords(center);
}
}
}
}
else
{
placeTerminalLoop(mbl,_r);
}
}
private void placeTerminalLoop(ArrayList<ModeleBase> mbl, RNA r)
{
if ((_children.size()==0)&&(_p._r.getNumPortions()==1))
{
Portion p = _p._r.getPortion(0);
if (p instanceof UnpairedPortion)
{
UnpairedPortion up = (UnpairedPortion) p;
double rad = determineRadius(1,up.getNumBases(),_r);
int a = _p._pos1+_p._len-1;
int b = _p._pos2-(_p._len-1);
ModeleBase mbLeft = mbl.get(a);
ModeleBase mbRight = mbl.get(b);
Point2D.Double pl = mbLeft.getCoords();
Point2D.Double pr = mbRight.getCoords();
Point2D.Double pm = new Point2D.Double((pl.x+pr.x)/2.0,(pl.y+pr.y)/2.0);
double vx = (pl.x-pr.x)/pl.distance(pr);
double vy = (pl.y-pr.y)/pl.distance(pr);
double vnx = -vy, vny = vx;
Point2D.Double pc = new Point2D.Double(pm.x+rad*vnx,pm.y+rad*vny);
double circ = r.LOOP_DISTANCE*(1.0+up.getNumBases())+r.BASE_PAIR_DISTANCE;
double incrLoop = Math.PI*2.0*r.LOOP_DISTANCE/circ;
double angle = Math.PI*2.0*r.BASE_PAIR_DISTANCE/(2.0*circ);
for (int j=0;j<up._len;j++)
{
int n = up._pos + j;
ModeleBase mb = mbl.get(n);
angle += incrLoop;
double dx = -Math.cos(angle)*vnx+Math.sin(angle)*vx;
double dy = -Math.cos(angle)*vny+Math.sin(angle)*vy;
// Point2D.Double pf = new Point2D.Double(pc.x,pc.y);
Point2D.Double pf = new Point2D.Double(pc.x+rad*dx,pc.y+rad*dy);
mb.setCoords(pf);
}
}
}
}
public String toString()
{
return "Emb.Hel.: "+_p.toString();
}
}
public double determineRadius(int numHelices, int numUnpaired, RNA r)
{
double circ = numHelices*r.BASE_PAIR_DISTANCE+(numHelices+numUnpaired)*r.LOOP_DISTANCE;
return circ/(2.0*Math.PI);
}
public void predrawTree(double x0, double y0, RNATree t, double dir, RNA r, HelixEmbedding parent, ArrayList<HelixEmbedding> all) throws Exception
{
double x=x0;
double y=y0;
int numHelices = 0;
int numUBases = 0;
double totCirc = r.BASE_PAIR_DISTANCE+r.LOOP_DISTANCE;
for (int i=0;i<t.getNumPortions();i++ )
{
Portion p = t.getPortion(i);
if (p instanceof PairedPortion)
{
totCirc += (r.BASE_PAIR_DISTANCE+r.LOOP_DISTANCE);
numHelices++;
}
else
{
totCirc += r.LOOP_DISTANCE*(p.getNumBases());
numUBases += p.getNumBases();
}
}
double radius = determineRadius(numHelices+1,numUBases,r);
int[] placement = new int[numHelices];
double inc = ((double)MAX_NUM_DIR)/((double)numHelices+1);
double val = inc;
for (int i=0;i<numHelices;i++ )
{
placement[i] = (int)Math.round(val);
val += inc;
}
double angleIncr = 2.0*Math.PI/(double)MAX_NUM_DIR;
x = x0+radius*Math.cos(dir+Math.PI);
y = y0+radius*Math.sin(dir+Math.PI);
int curH = 0;
for (int i=0;i<t.getNumPortions();i++ )
{
Portion p = t.getPortion(i);
if (p instanceof PairedPortion)
{
double ndir = dir + placement[curH]*angleIncr;
PairedPortion pp = (PairedPortion) p;
for(int j=0;j<pp._len;j++)
{
int i1 = pp._pos1+j;
int i2 = pp._pos2-j;
double vx = Math.cos(ndir);
double vy = Math.sin(ndir);
double nx = x+(((j)*r.LOOP_DISTANCE+radius)*vx);
double ny = y+(((j)*r.LOOP_DISTANCE+radius)*vy);
r.get_listeBases().get(i1).setCoords(new Point2D.Double(nx+r.BASE_PAIR_DISTANCE*vy/ 2.0,ny-r.BASE_PAIR_DISTANCE*vx/ 2.0));
r.get_listeBases().get(i2).setCoords(new Point2D.Double(nx-r.BASE_PAIR_DISTANCE*vy/ 2.0,ny+r.BASE_PAIR_DISTANCE*vx/ 2.0));
}
double nx = x+(((pp._len-1)*r.LOOP_DISTANCE+radius)*Math.cos(ndir));
double ny = y+(((pp._len-1)*r.LOOP_DISTANCE+radius)*Math.sin(ndir));
HelixEmbedding nh = new HelixEmbedding(new Point2D.Double(x,y),pp,r,parent);
parent.addHelixEmbedding(nh,placement[curH]);
all.add(nh);
predrawTree(nx, ny, pp._r, ndir+Math.PI, r, nh, all);
curH++;
}
else if (p instanceof UnpairedPortion)
{
UnpairedPortion up = (UnpairedPortion) p;
for(int j=0;j<up._len;j++)
{
r.get_listeBases().get(up._pos+j).setCoords(new Point2D.Double(x,y));
}
}
//System.out.println(dir);
}
}
public static Random _rnd = new Random();
private static int MAX_NUM_DIR = 8;
public RNATree drawRNA(double dirAngle, RNA r) {
RNATree t = new RNATree();
buildTree(0, r.get_listeBases().size() - 1, t, r );
System.out.println(t);
ArrayList<HelixEmbedding> all = new ArrayList<HelixEmbedding>();
HelixEmbedding root = null;
try {
root = new HelixEmbedding(new Point2D.Double(0.0,0.0),new PairedPortion(0,0,0,t),r,null);
predrawTree(0,0,t,0.0,r,root,all);
int steps=1000;
double prevbadness = Double.MAX_VALUE;
while((steps>0)&&(prevbadness>0))
{
// Generating new structure
HelixEmbedding chosen = all.get(_rnd.nextInt(all.size()));
int delta = chosen.chooseNextMove();
// Draw current
if (_vp!=null)
{
GeneralPath p = new GeneralPath();
for (int i=0;i<all.size();i++)
{ p.append(all.get(i).getShape(),false); }
r._debugShape = p;
_vp.paintImmediately(0, 0, _vp.getWidth(), _vp.getHeight());
}
//Evaluating solution
double badness = 0.0;
for (int i=0;i<all.size();i++)
{
Shape s1 = all.get(i).getShape();
for (int j=i+1;j<all.size();j++)
{
Shape s2 = all.get(j).getShape();
Area a = new Area(s1);
a.intersect(new Area(s2));
if (!a.isEmpty())
{
badness ++;
}
}
}
if (badness-prevbadness>0)
{
chosen.cancelMove(delta);
}
else
{
prevbadness = badness;
}
System.out.println(badness);
steps--;
}
if (root!=null)
{ root.reflectCoordinates(); }
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return t;
};
}