cz.vutbr.fit.layout.segm.op.SeparatorSetHVS Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fitlayout-segm-base Show documentation
Show all versions of fitlayout-segm-base Show documentation
FitLayout - Basic segmentation algorithm and area tree operators.
The newest version!
/**
* SeparatorSetHVS.java
*
* Created on 24.5.2011, 14:44:33 by burgetr
*/
package cz.vutbr.fit.layout.segm.op;
import java.util.Iterator;
import java.util.Vector;
import cz.vutbr.fit.layout.model.Area;
import cz.vutbr.fit.layout.model.Rectangular;
/**
* A horizntal/vertical separator detection with shrinking. The separator set is created by splitting the horizontal and vertical separators independently.
* Additionally, we shring the vertical separators to the minimal length that separates the boxes - i.e. there is no separator considered between empty spaces.
* @author radek
*/
public class SeparatorSetHVS extends SeparatorSet
{
/**
* Creates a new separator set with one horizontal and one vertical separator.
*/
public SeparatorSetHVS(Area root)
{
super(root);
}
/**
* Creates a new separator set with one horizontal and one vertical separator.
*/
public SeparatorSetHVS(Area root, Area filter)
{
super(root, filter);
}
//=====================================================================================
/**
* Finds the horizontal and vertical list of separators
* @param area the root area
* @param filter if not null, only the sub areas enclosed in the filter area
* are considered
*/
@Override
protected void findSeparators(Area area, Area filter)
{
hsep = new Vector();
vsep = new Vector();
Area base = (filter == null) ? area : filter;
Separator hinit = new Separator(Separator.HORIZONTAL,
base.getX1(),
base.getY1(),
base.getX2(),
base.getY2());
hsep.add(hinit);
Separator vinit = new Separator(Separator.VERTICAL,
base.getX1(),
base.getY1(),
base.getX2(),
base.getY2());
vsep.add(vinit);
if (considerSubareas(this.root, filter) > 1)
{
//System.out.println("Filter: " + filter);
Vector areas = createAreas(filter);
//System.out.println("Start: " + areas.size() + " areas"); wait(5000);
if (areas.size() > 1)
{
for (Iterator it = areas.iterator(); it.hasNext(); )
{
Area a = it.next();
//System.out.println("Area: " + a);
//dispRect(a.getBounds(), java.awt.Color.RED); wait(100);
SeparatorSet aset = new SeparatorSetHVS(area, a);
hsep.addAll(aset.getHorizontal());
vsep.addAll(aset.getVertical());
}
}
}
else
{
hsep.removeAllElements();
vsep.removeAllElements();
}
applyRegularFilters();
}
/**
* Consider a new area -- updates the separators according to this new area
* @param area The new area node to be considered
*/
private void considerArea(Area area)
{
//area coordinates
int ax1 = area.getX1();
int ay1 = area.getY1();
int ax2 = area.getX2();
int ay2 = area.getY2();
//go through horizontal separators
Vector newseps = new Vector();
for (Iterator it = hsep.iterator(); it.hasNext();)
{
Separator sep = it.next();
int sy1 = sep.getY1();
int sy2 = sep.getY2();
//the box covers the separator -- remove the separator
if (ay1 <= sy1 && ay2 >= sy2)
{
it.remove();
}
//box entirely inside -- split the separator
else if (ay1 > sy1 && ay2 < sy2)
{
Separator newsep = new Separator(Separator.HORIZONTAL,
sep.getX1(), ay2 + 1,
sep.getX2(), sep.getY2());
newseps.add(newsep);
sep.setY2(ay1 - 1);
newsep.setArea1(area);
sep.setArea2(area);
}
//box partially covers the separator -- update the separator
else if ((ay1 > sy1 && ay1 <= sy2) && ay2 >= sy2)
{
sep.setY2(ay1 - 1);
sep.setArea2(area);
}
//box partially covers the separator -- update the separator
else if (ay1 <= sy1 && (ay2 >= sy1 && ay2 < sy2))
{
sep.setY1(ay2 + 1);
sep.setArea1(area);
}
}
hsep.addAll(newseps);
//go through vertical separators
newseps = new Vector();
for (Iterator it = vsep.iterator(); it.hasNext();)
{
Separator sep = it.next();
int sx1 = sep.getX1();
int sx2 = sep.getX2();
//the box covers the separator -- remove the separator
if (ax1 <= sx1 && ax2 >= sx2)
{
it.remove();
}
//box entirely inside -- split the separator
else if (ax1 > sx1 && ax2 < sx2)
{
Separator newsep = new Separator(Separator.VERTICAL,
ax2 + 1, sep.getY1(),
sep.getX2(), sep.getY2());
newseps.add(newsep);
sep.setX2(ax1 - 1);
newsep.setArea1(area);
sep.setArea2(area);
}
//box partially covers the separator -- update the separator
else if ((ax1 > sx1 && ax1 <= sx2) && ax2 >= sx2)
{
sep.setX2(ax1 - 1);
sep.setArea2(area);
}
//box partially covers the separator -- update the separator
else if (ax1 <= sx1 && (ax2 >= sx1 && ax2 < sx2))
{
sep.setX1(ax2 + 1);
sep.setArea1(area);
}
}
vsep.addAll(newseps);
}
/**
* Recursively considers all the sub areas and updates the list of
* separators.
* @param area the root area
* @param filter if not null, only the sub areas enclosed in the filter area are considered
* @return the number of processed subareas
*/
private int considerSubareas(Area area, Area filter)
{
int ret = 0;
for (int i = 0; i < area.getChildCount(); i++)
{
Area sub = area.getChildAt(i);
if (filter == null || filter.getBounds().encloses(sub.getBounds()))
{
if (sub.isHorizontalSeparator())
{
}
else if (sub.isVerticalSeparator())
{
}
else
{
//dispSeparators();
//System.out.println("Consider: " + sub);
//dispRect(sub.getArea().getBounds(), java.awt.Color.GREEN); wait(200);
//if (sub.toString().contains("MediaEval"))
// System.out.println("jo!");
considerArea(sub);
ret++;
}
}
}
applyRegularFilters();
return ret;
}
//=====================================================================================
/**
* Add a separator and split or update the areas if necessary.
*/
private void considerSeparator(Vector areas, Separator sep, boolean horizontal)
{
//dispRect(sep, java.awt.Color.GREEN); wait(1000);
Vector newareas = new Vector();
if (horizontal) //horizontal separator
{
int sy1 = sep.getY1();
int sy2 = sep.getY2();
for (Iterator it = areas.iterator(); it.hasNext();)
{
Area area = it.next();
int ay1 = area.getY1();
int ay2 = area.getY2();
//the separator covers the area -- remove the area
if (sy1 <= ay1 && sy2 >= ay2)
{
it.remove();
}
//separator entirely inside -- split the area
else if (sy1 > ay1 && sy2 < ay2)
{
Area newarea = area.getAreaTree().createArea(new Rectangular(area.getX1(), sy2 + 1,
area.getX2(), area.getY2()));
newareas.add(newarea);
area.getBounds().setY2(sy1 - 1);
}
//separator partially covers the area -- update the area
else if ((sy1 > ay1 && sy1 <= ay2) && sy2 >= ay2)
{
area.getBounds().setY2(sy1 - 1);
}
//separator partially covers the area -- update the area
else if (sy1 <= ay1 && (sy2 >= ay1 && sy2 < ay2))
{
area.getBounds().setY1(sy2 + 1);
}
}
}
else //vertical separator
{
int sx1 = sep.getX1();
int sx2 = sep.getX2();
for (Iterator it = areas.iterator(); it.hasNext();)
{
Area area = it.next();
int ax1 = area.getX1();
int ax2 = area.getX2();
//the separator covers the area -- remove the area
if (sx1 <= ax1 && sx2 >= ax2)
{
it.remove();
}
//separator entirely inside -- split the area
else if (sx1 > ax1 && sx2 < ax2)
{
Area newarea = area.getAreaTree().createArea(new Rectangular(sx2 + 1, area.getY1(),
area.getX2(), area.getY2()));
newareas.add(newarea);
area.getBounds().setX2(sx1 - 1);
}
//separator partially covers the area -- update the area
else if ((sx1 > ax1 && sx1 <= ax2) && sx2 >= ax2)
{
area.getBounds().setX2(sx1 - 1);
}
//separator partially covers the area -- update the area
else if (sx1 <= ax1 && (sx2 >= ax1 && sx2 < ax2))
{
area.getBounds().setX1(sx2 + 1);
}
}
}
areas.addAll(newareas);
}
/**
* Add a separator but do not consider its width (zero-width separator). Split or update the areas if necessary.
* Thin separators are considered only when they span for the whole width/height of the processed area.
*/
private void considerThinSeparator(Vector areas, Separator sep, boolean horizontal)
{
Vector newareas = new Vector();
if (horizontal) //horizontal separator
{
int sy1 = sep.getY1();
int sy2 = sep.getY2();
for (Iterator it = areas.iterator(); it.hasNext();)
{
Area area = it.next();
//the separator width must cover the whole area
if (sep.getX1() <= area.getX1() && sep.getX2() >= area.getX2())
{
int ay1 = area.getY1();
int ay2 = area.getY2();
//the separator covers the area -- remove the area
if (sy1 <= ay1 && sy2 >= ay2)
{
it.remove();
}
//separator entirely inside -- split the area
else if (sy1 > ay1 && sy2 < ay2)
{
Area newarea = area.getAreaTree().createArea(new Rectangular(area.getX1(), sy1,
area.getX2(), area.getY2()));
newareas.add(newarea);
area.getBounds().setY2(sy1 - 1);
}
//separator partially covers the area -- update the area
else if ((sy1 > ay1 && sy1 < ay2) && sy2 >= ay2)
{
area.getBounds().setY2(sy1 - 1);
}
//separator partially covers the area -- update the area
else if (sy1 <= ay1 && (sy2 > ay1 && sy2 < ay2))
{
area.getBounds().setY1(sy1);
}
}
}
}
else //vertical separator
{
int sx1 = sep.getX1();
int sx2 = sep.getX2();
for (Iterator it = areas.iterator(); it.hasNext();)
{
Area area = it.next();
//the separator height must cover the whole area
if (sep.getY1() <= area.getY1() && sep.getY2() >= area.getY2())
{
int ax1 = area.getX1();
int ax2 = area.getX2();
//the separator covers the area -- remove the area
if (sx1 <= ax1 && sx2 >= ax2)
{
it.remove();
}
//separator entirely inside -- split the area
else if (sx1 > ax1 && sx2 < ax2)
{
Area newarea = area.getAreaTree().createArea(new Rectangular(sx1, area.getY1(),
area.getX2(), area.getY2()));
newareas.add(newarea);
area.getBounds().setX2(sx1 - 1);
}
//separator partially covers the area -- update the area
else if ((sx1 > ax1 && sx1 < ax2) && sx2 >= ax2)
{
area.getBounds().setX2(sx1 - 1);
}
//separator partially covers the area -- update the area
else if (sx1 <= ax1 && (sx2 > ax1 && sx2 < ax2))
{
area.getBounds().setX1(sx1);
}
}
}
}
areas.addAll(newareas);
}
/**
* Creates new "virtual" visual areas based on detected separators. These areas are further used for detecting more separators.
* @param an optional filtering area; only the new sub-areas within this area are considered
* @return a vector of created visual areas
*/
private Vector createAreas(Area filter)
{
Area base = (filter == null) ? root : filter;
Vector areas = new Vector();
Area init = base.getAreaTree().createArea(
new Rectangular(base.getX1(), base.getY1(), base.getX2(), base.getY2()));
areas.add(init);
for (Separator sep : hsep)
considerSeparator(areas, sep, true);
for (Separator sep : vsep)
considerSeparator(areas, sep, false);
for (Separator sep : bsep)
considerThinSeparator(areas, sep, sep.getType() == Separator.BOXH);
return areas;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy