org.diamondspin
Class DSFrontierManager

java.lang.Object
  extended by org.diamondspin.DSFrontierManager

public class DSFrontierManager
extends Object


Nested Class Summary
protected  class DSFrontierManager.DSFrontierManagerHelper
           
 
Field Summary
static int ASK
           
static int CLIP
           
static int CLIP_EXT
           
static int FOLD
           
protected  HashMap<DSFrame,DSFrontierManager.DSFrontierManagerHelper> helpers
           
 BufferedImage img
           
static int MAX_OP
           
static int MOVE
           
static int NOT_USED
           
protected  int[] oper
           
protected  int oper_num
           
protected  Point2D.Double p
           
protected  DSFrame r
           
static int RESIZE
           
static int ROTATE
           
static int USED_NOT_SOLVED
           
static int USED_SOLVED
           
protected  Point2D.Double v
           
static int ZOOM
           
 
Constructor Summary
DSFrontierManager(Point2D.Double a, double vx, double vy, DSFrame relative, int o)
           
DSFrontierManager(Point2D.Double a, Point2D.Double vect_dir, DSFrame relative, int o)
           
DSFrontierManager(Point2D.Double a, Point2D.Double b, DSFrame relative, int o, boolean unused)
           
 
Method Summary
 void addOperation(int o)
          perform the operation o if the existing ones failled
 void changeFrontier(Point a, Point vect_dir)
           
protected  void checkFrontier(DSFrame f, DSFrontierManager.DSFrontierManagerHelper h)
          Check if f is corssing the frontier.
 void freeFrame(DSFrame f)
           
protected  double getFrontierDist(double x, double y)
           
protected  double getFrontierDist(Point2D.Double fp)
          Get the ORIENTED minimal distance between the point FP and the frontier line.
 int getFrontierSide(DSFrame f)
          Is f on the left or the right of the fontier ? We use only the Center of f to compute this.
 double getMaximumFrontierDist(DSFrame f)
           
 double getMaximumFrontierDist(DSFrame f, Point2D.Double max_dist_point)
           
protected  double getMaximumFrontierDist(PathIterator pi, Point2D.Double max_dist_point)
          PI points must be in global corrdinates.
 boolean isCrossingFrontier(DSFrame f)
          Check is f is crossing the border.
 void manageFrame(DSFrame f)
           
protected  int numCrossingFrontier(double referenceSide, PathIterator pi)
           
 int numCrossingFrontier(DSFrame f)
          Return the number of corners of others special points of F which are not on the SAME side than the center of F.
protected  boolean opClip(DSFrame f)
           
protected  boolean opFold(DSFrame f)
           
protected  boolean opMove(DSFrame f)
           
protected  boolean opResize(DSFrame f)
           
protected  boolean opRotate(DSFrame f)
          F is crossing the border.
protected  boolean opuClip(DSFrame f, DSFrontierManager.DSFrontierManagerHelper h)
           
protected  boolean opuFold(DSFrame f, DSFrontierManager.DSFrontierManagerHelper h)
           
protected  boolean opuMove(DSFrame f, DSFrontierManager.DSFrontierManagerHelper h)
           
protected  boolean opuResize(DSFrame f, DSFrontierManager.DSFrontierManagerHelper h)
           
protected  boolean opuRotate(DSFrame f, DSFrontierManager.DSFrontierManagerHelper h)
          We will try to unrotate F to make f.getBeta() approching h.o_beta modulo 2PI.
protected  boolean opuZoom(DSFrame f, DSFrontierManager.DSFrontierManagerHelper h)
          Here's the deal : F is no more crossing the border.
protected  boolean opZoom(DSFrame f)
          Here's the deal : F is crossing the border.
 void paint(Graphics2D g)
           
 void setOperation(int o)
          Clear the op list and set oper[0] to o
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

ASK

public static final int ASK
See Also:
Constant Field Values

CLIP

public static final int CLIP
See Also:
Constant Field Values

MOVE

public static final int MOVE
See Also:
Constant Field Values

ZOOM

public static final int ZOOM
See Also:
Constant Field Values

RESIZE

public static final int RESIZE
See Also:
Constant Field Values

FOLD

public static final int FOLD
See Also:
Constant Field Values

ROTATE

public static final int ROTATE
See Also:
Constant Field Values

NOT_USED

public static final int NOT_USED
See Also:
Constant Field Values

USED_NOT_SOLVED

public static final int USED_NOT_SOLVED
See Also:
Constant Field Values

USED_SOLVED

public static final int USED_SOLVED
See Also:
Constant Field Values

CLIP_EXT

public static final int CLIP_EXT
See Also:
Constant Field Values

MAX_OP

public static final int MAX_OP
See Also:
Constant Field Values

p

protected Point2D.Double p

v

protected Point2D.Double v

r

protected DSFrame r

helpers

protected HashMap<DSFrame,DSFrontierManager.DSFrontierManagerHelper> helpers

oper

protected int[] oper

oper_num

protected int oper_num

img

public BufferedImage img
Constructor Detail

DSFrontierManager

public DSFrontierManager(Point2D.Double a,
                         Point2D.Double b,
                         DSFrame relative,
                         int o,
                         boolean unused)

DSFrontierManager

public DSFrontierManager(Point2D.Double a,
                         double vx,
                         double vy,
                         DSFrame relative,
                         int o)

DSFrontierManager

public DSFrontierManager(Point2D.Double a,
                         Point2D.Double vect_dir,
                         DSFrame relative,
                         int o)
Method Detail

changeFrontier

public void changeFrontier(Point a,
                           Point vect_dir)

setOperation

public void setOperation(int o)
Clear the op list and set oper[0] to o


addOperation

public void addOperation(int o)
perform the operation o if the existing ones failled


manageFrame

public void manageFrame(DSFrame f)

freeFrame

public void freeFrame(DSFrame f)

paint

public void paint(Graphics2D g)
To do:
for debug only. DSTabletop size (1280 * 1024) hardcoded

isCrossingFrontier

public boolean isCrossingFrontier(DSFrame f)
Check is f is crossing the border.

To do:
We could do it simplier by checking for each corner of both shapes of f if they are all on the same side of the frontier protected boolean isCrossingFrontier_Old(DSFrame f){ Point sp = (r == null ? p : r.transformPoint(p)); Point sv = (r == null ? v : r.transformVector(v)); Point lp = f.inversePoint(sp); Point lv = f.inverseVector(sv); lp.translate(f.center.x, f.center.y); /* lp : point de la bordure dans les coord locales de f v : vecteur directeur dans les mêmes coord locales (pas pour les translations mais pour les rotations) * / /* On cherche à savoir si la droite (lp, lv) coupe la shape f.getFoldShapeFront() * / /* Line2D représente en fait... un segment ! * / //Line2D l = new Line2D.double(lp.x - CLIP_EXT * lv.x, lp.y - CLIP_EXT * lv.y, // lp.x + CLIP_EXT * lv.x, lp.y + CLIP_EXT * lv.y); /* Les Area ne peuvent pas représenter des lignes :-( Alors on va faire un rectangle très fin (2px), mais il ne faut pas que la direction de notre rectangle soit alignée avec la droite. Alors on essaie de trouver l'alignement modulo 45° le plus à angle droit * / int dx, dy; if(lv.x > 0){ if(lv.y > 0){ dx = 1; dy = -1; } else if(lv.y < 0) { dx = -1; dy = -1; } else{ dx = 0; dy = -1; } }else if(lv.x < 0){ if(lv.y > 0){ dx = 1; dy = 1; } else if(lv.y < 0) { dx = -1; dy = 1; } else{ dx = 0; dy = 1; } }else{ if(lv.y > 0){ dx = 1; dy = 0; } else if(lv.y < 0) { dx = -1; dy = 0; } else{ dx = 0; dy = 0; } // ne devrait pas arriver, vect dir != (0, 0) } Polygon l = new Polygon(); l.addPoint(lp.x - CLIP_EXT * lv.x + dx, lp.y - CLIP_EXT * lv.y + dy); l.addPoint(lp.x - CLIP_EXT * lv.x , lp.y - CLIP_EXT * lv.y ); l.addPoint(lp.x + CLIP_EXT * lv.x , lp.y + CLIP_EXT * lv.y ); l.addPoint(lp.x + CLIP_EXT * lv.x + dx, lp.y + CLIP_EXT * lv.y + dx); Area al = new Area(l); Area rframe; if(f.getFoldShapeFront() != null) rframe = new Area(f.getFoldShapeFront()); else rframe = new Area(f.getBounds()); al.intersect(rframe); /** If the intersection of the front shape of f and the border line is empty, then it mean they don't intersect, and we proceed to test the back. Else, we return true. / if(!al.isEmpty()){ return true; } if(f.getFoldProportion() > 0){ Point bp = f.inversePointBack(sp); Point bv = f.inverseVectorBack(sv); bp.translate(f.center.x, f.center.y); //bv.translate(f.center.x, f.center.y); //l = new Line2D.double(bp.x - CLIP_EXT * bv.x, bp.y - CLIP_EXT * bv.y, // bp.x + CLIP_EXT * bv.x, bp.y + CLIP_EXT * bv.y); if(bv.x > 0){ if(bv.y > 0){ dx = 1; dy = -1; } else if(bv.y < 0) { dx = -1; dy = -1; } else{ dx = 0; dy = -1; } }else if(bv.x < 0){ if(bv.y > 0){ dx = 1; dy = 1; } else if(bv.y < 0) { dx = -1; dy = 1; } else{ dx = 0; dy = 1; } }else{ if(bv.y > 0){ dx = 1; dy = 0; } else if(bv.y < 0) { dx = -1; dy = 0; } else{ dx = 0; dy = 0; } // ne devrait pas arriver, vect dir != (0, 0) } l = new Polygon(); l.addPoint(bp.x - CLIP_EXT * bv.x + dx, bp.y - CLIP_EXT * bv.y + dy); l.addPoint(bp.x - CLIP_EXT * bv.x , bp.y - CLIP_EXT * bv.y ); l.addPoint(bp.x + CLIP_EXT * bv.x , bp.y + CLIP_EXT * bv.y ); l.addPoint(bp.x + CLIP_EXT * bv.x + dx, bp.y + CLIP_EXT * bv.y + dx); al = new Area(l); rframe = new Area(f.getFoldShapeBack()); al.intersect(rframe); if(!al.isEmpty()) return true; } return false; }

numCrossingFrontier

public int numCrossingFrontier(DSFrame f)
Return the number of corners of others special points of F which are not on the SAME side than the center of F.


numCrossingFrontier

protected int numCrossingFrontier(double referenceSide,
                                  PathIterator pi)

getMaximumFrontierDist

public double getMaximumFrontierDist(DSFrame f)

getMaximumFrontierDist

public double getMaximumFrontierDist(DSFrame f,
                                     Point2D.Double max_dist_point)

getMaximumFrontierDist

protected double getMaximumFrontierDist(PathIterator pi,
                                        Point2D.Double max_dist_point)
PI points must be in global corrdinates. P is a 'out' variable, must not be null and is returned in global coordinates.


getFrontierSide

public int getFrontierSide(DSFrame f)
Is f on the left or the right of the fontier ? We use only the Center of f to compute this. Use getFrontierSide in conjunction with isCrossingFrontier to know if f is actually on both side of the frontier. The left or right is understood to be when you are at the point P and looking in the direction of Vect_Dir or of B. The left is intented to be the side on which the documents are. The frontier will prevent them to go the the right side (or clip the part over the right side)

Returns:
Return -1 if f is on the left. Return +1 if f if on the right. Return 0 is f's center is exactly on the frontier or if there is an error or something like that.

getFrontierDist

protected double getFrontierDist(Point2D.Double fp)
Get the ORIENTED minimal distance between the point FP and the frontier line. Distance is < 0 if left, and > 0 if right. See getFrontierSide for meaning of left and right. FP must be in global coordinate. The maths partially come from http://perso.ensad.fr/ari/davidov/prog/encarts/droite.htm#pos


getFrontierDist

protected double getFrontierDist(double x,
                                 double y)

checkFrontier

protected void checkFrontier(DSFrame f,
                             DSFrontierManager.DSFrontierManagerHelper h)
Check if f is corssing the frontier. If it is, put it on the right side of the frontier

To do:
optimization. Use cached variables

opZoom

protected boolean opZoom(DSFrame f)
Here's the deal : F is crossing the border. We try to correct it. First, we check that the center hasn't crossed the border. If it has, we put the lowest scale possible and return false. A move will hopefully complete the operation. If it hasn't, we compute the needed scale. For that we need to know which point is the farther away of the border on the wrong (positve) side. Scale = Dist(Frontier, Point) / Dist(Center, Point). If it is smaller than the lowest scale, we apply it and return true. If it isn't, we put the lowest scale possible and return false. To compute Dist(Frontier, Point) / Dist(Center, Point) more effitiently, we use Thales. We have d = Dist(P, Proj(P on frontier) and c = Dist(C, Proj(C on frontier). Scale = CF / CP = CF / (CF + PF) = 1 / ((CF + PF) / CF) = 1 / (1 + PF/CF) = 1 / (1 + (d / c)) We multiply the old scale by the new one because distances in pixel used in the computation are already impacted by the old scale.

Returns:
true if it's now OK, false if more actions are needed

opuZoom

protected boolean opuZoom(DSFrame f,
                          DSFrontierManager.DSFrontierManagerHelper h)
Here's the deal : F is no more crossing the border. We try to set the scale back to its original value. First, that the scale is not already to its original value. If it is, we return true. If it isn't, we compute the needed scale like opZoom.

Returns:
true if totally undone, false if still active

opRotate

protected boolean opRotate(DSFrame f)
F is crossing the border. We want to correct it by rotating f arround its center (i.e. modifying its beta). We will assume that only ONE point is crossing the border. We use tree points. C, le center of the windows, P, the point we is crossing the border, and F and F', the points of the frontier with CF = CF' = CP. We compute the signed angles FCP and F'CP. We take the smaller, in absolute value, and add it to the existing beta. First, we check that the center hasn't crossed the border. If it has, we won't be able to correct the problem, but we could at least minimize the area that has cross the border. This is not implemented.

Returns:
true if it's now OK, false if more actions are needed

opuRotate

protected boolean opuRotate(DSFrame f,
                            DSFrontierManager.DSFrontierManagerHelper h)
We will try to unrotate F to make f.getBeta() approching h.o_beta modulo 2PI.

Returns:
true if totally undone, false if still active

opMove

protected boolean opMove(DSFrame f)

opuMove

protected boolean opuMove(DSFrame f,
                          DSFrontierManager.DSFrontierManagerHelper h)

opClip

protected boolean opClip(DSFrame f)

opuClip

protected boolean opuClip(DSFrame f,
                          DSFrontierManager.DSFrontierManagerHelper h)

opResize

protected boolean opResize(DSFrame f)

opuResize

protected boolean opuResize(DSFrame f,
                            DSFrontierManager.DSFrontierManagerHelper h)

opFold

protected boolean opFold(DSFrame f)

opuFold

protected boolean opuFold(DSFrame f,
                          DSFrontierManager.DSFrontierManagerHelper h)


Copyright © 2006 Frederic Vernier(LIMSI) Chia Shen(MERL) Guillaume Besacier(LIMSI). All Rights Reserved.