//----------------------------------------------------------------------------//
// //
// S e c t i o n //
// //
//----------------------------------------------------------------------------//
// <editor-fold defaultstate="collapsed" desc="hdr"> //
// Copyright © Hervé Bitteur and others 2000-2013. All rights reserved. //
// This software is released under the GNU General Public License. //
// Goto http://kenai.com/projects/audiveris to report bugs or suggestions. //
//----------------------------------------------------------------------------//
// </editor-fold>
package omr.lag;
import omr.glyph.facets.Glyph;
import omr.graph.Vertex;
import omr.lag.ui.SectionView;
import omr.math.Barycenter;
import omr.math.Line;
import omr.math.PointsCollector;
import omr.run.Orientation;
import omr.run.Oriented;
import omr.run.Run;
import omr.sheet.SystemInfo;
import omr.stick.StickRelation;
import omr.util.Vip;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.geom.PathIterator;
import java.awt.image.BufferedImage;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
/**
* Interface {@code Section} handles a section of contiguous and
* compatible {@link Run} instances.
*
* <p> A section carries orientation information, which is the orientation for
* all runs in this section.
*
* <ol> <li> Positions increase in parallel with run numbers, so the thickness
* of a section is defined as the delta between last and first positions, in
* other words its number of runs. </li>
*
* <li> Coordinates increase along any section run, so the section start is the
* minimum of all run starting coordinates, and the section stop is the maximum
* of all run stopping coordinates. We define section length as the value: stop
* - start +1 </li> </ol>
*
* <p><b>Beware</b>, the section orientation only governs the runs orientation.
* It by no means implies that the section dimension is longer in the direction
* along the runs than in the direction across.
* To enforce this, the {@link #getLength(Orientation)} requires that an
* explicit orientation be provided, just like for {@link Glyph} instances.
*
* @author Hervé Bitteur
*/
@XmlJavaTypeAdapter(BasicSection.Adapter.class)
public interface Section
extends Vertex<Lag, Section>, Comparable<Section>, Oriented, SectionView, Vip
{
//~ Static fields/initializers ---------------------------------------------
/** A section comparator, using section id */
public static final Comparator<Section> idComparator = new Comparator<Section>()
{
@Override
public int compare (Section s1,
Section s2)
{
return Integer.signum(s1.getId() - s2.getId());
}
};
/** For comparing Section instances on their decreasing weight */
public static final Comparator<Section> reverseWeightComparator = new Comparator<Section>()
{
@Override
public int compare (Section s1,
Section s2)
{
return Integer.signum(s2.getWeight() - s1.getWeight());
}
};
/** For comparing Section instances on their start value */
public static final Comparator<Section> startComparator = new Comparator<Section>()
{
@Override
public int compare (Section s1,
Section s2)
{
return s1.getStartCoord() - s2.getStartCoord();
}
};
/** For comparing Section instances on their pos value */
public static final Comparator<Section> posComparator = new Comparator<Section>()
{
@Override
public int compare (Section s1,
Section s2)
{
return s1.getFirstPos() - s2.getFirstPos();
}
};
//~ Methods ----------------------------------------------------------------
/**
* Register the adjacency of a section from the other orientation.
*
* @param otherSection the other section to remember
*/
public void addOppositeSection (Section otherSection);
/**
* Extend a section with the given run.
* This new run is assumed to be contiguous to the current last run of the
* section, no check is performed.
*
* @param run the new last run
*/
public void append (Run run);
/**
* Compute the various cached parameters from scratch.
*/
public void computeParameters ();
/**
* Predicate to check whether the given absolute point is located
* inside the section.
*
* @param x absolute abscissa
* @param y absolute ordinate
* @return true if absolute point(x,y) is contained in the section
*/
public boolean contains (int x,
int y);
/**
* Cumulate in the provided absolute Barycenter the section pixels
* that are contained in the provided roi Rectangle.
* If the roi is null, all pixels are cumulated into the barycenter.
*
* @param barycenter the absolute point to populate
* @param absRoi the absolute rectangle of interest
*/
public void cumulate (Barycenter barycenter,
Rectangle absRoi);
/**
* Cumulate all points that compose the runs of the section, into
* the provided <b>absolute</b> collector.
*
* @param collector the absolute points collector to populate
*/
public void cumulate (PointsCollector collector);
/**
* Draws a basic representation of the section, using ascii chars.
*/
public void drawAscii ();
/**
* Build an image with the pixels of this section.
*
* @param im the image to populate with this section
* @param box absolute bounding box (used as image coordinates reference)
*/
public void fillImage (BufferedImage im,
Rectangle box);
/**
* Draws the section, into the provided table.
*/
public void fillTable (char[][] table,
Rectangle box);
/**
* Return the <b>absolute</b> line which best approximates the
* section.
*
* @return the absolute fitted line
* @see #getOrientedLine()
*/
public Line getAbsoluteLine ();
/**
* Report the section area absolute center.
*
* @return the area absolute center
*/
public Point getAreaCenter ();
/**
* Report the ratio of length over thickness, along provided
* orientation.
*
* @return the "slimness" of the section
*/
public double getAspect (Orientation orientation);
/**
* Return a COPY of the absolute bounding box.
*
* @return the absolute bounding box
*/
@Override
public Rectangle getBounds ();
/**
* Return the absolute point which is at the mass center of the
* section, with all pixels considered of equal weight.
*
* @return the mass center of the section, as a absolute point
*/
public Point getCentroid ();
/**
* Return the adjacency ratio on the incoming junctions.
* This is computed as the ratio to the length of the first run, of the
* sum of run overlapping lengths of the incoming junctions. In other
* words, this is a measure of how much the section at hand is
* overlapped with runs.
*
* <ul> <li> An isolated section/vertex, such as the one related to a
* barline, will exhibit a very low adjacency ratio. </li>
*
* <li> On the contrary, a section which is just a piece of a larger glyph,
* such as a treble clef or a brace, will have a higher adjacency. </li>
* </ul>
*
* @return the percentage of overlapped run length
* @see #getLastAdjacency
*/
public double getFirstAdjacency ();
/**
* Return the position (x for vertical runs, y for horizontal runs)
* of the first run of the section.
*
* @return the position
*/
public int getFirstPos ();
/**
* Return the first run within the section.
*
* @return the run, which always exists
*/
public Run getFirstRun ();
/**
* Return the contribution of the section to the foreground.
*
* @return the section foreground weight
*/
public int getForeWeight ();
/**
* Report the glyph the section belongs to, if any.
*
* @return the glyph, which may be null
*/
public Glyph getGlyph ();
/**
* Return the adjacency ratio at the end of the section at hand.
* See getFirstAdjacency for explanation of the role of adjacency.
*
* @return the percentage of overlapped run length
* @see #getFirstAdjacency
*/
public double getLastAdjacency ();
/**
* Return the position of the last run of the section.
*
* @return the position of last run
*/
public int getLastPos ();
/**
* Return the last run of the section.
*
* @return this last run (rightmost run for vertical section)
*/
public Run getLastRun ();
/**
* Return the length of the section, using the provided orientation.
*/
public int getLength (Orientation orientation);
/**
* Return the mean gray level of the section.
*
* @return the section foreground level (0 -> 255)
*/
public int getLevel ();
/**
* Return the size of the longest run in the section.
*
* @return the maximum run length
*/
public int getMaxRunLength ();
/**
* Report the ratio of length over mean thickness, using the
* provided orientation.
*
* @return the "slimness" of the section
*/
public double getMeanAspect (Orientation orientation);
/**
* Return the average value for all run lengths in the section.
*
* @return the mean run length
*/
public int getMeanRunLength ();
/**
* Report the average thickness of the section, using the provided
* orientation.
*
* @return the average thickness of the section
*/
public double getMeanThickness (Orientation orientation);
/**
* A read-only access to adjacent sections from opposite orientation
*
* @return the set of adjacent sections of the opposite orientation
*/
public Set<Section> getOppositeSections ();
/**
* Return the section bounding rectangle, using the runs
* orientation.
* Please clone it if you want to modify it afterwards
*
* @return the section bounding rectangle
*/
public Rectangle getOrientedBounds ();
/**
* Report the line which best approximates the section, using the
* runs orientation.
*
* @return the oriented fitted line
* @see #getAbsoluteLine()
*/
public Line getOrientedLine ();
/**
* Create an iterator along the absolute polygon that represents
* the section contour.
*
* @return an iterator on the underlying polygon
*/
public PathIterator getPathIterator ();
/**
* Return the absolute polygon that defines the display contour.
*
* @return the absolute perimeter contour
*/
public Polygon getPolygon ();
/**
* Report the absolute centroid of the section pixels found in the
* provided absolute region of interest.
*
* @param absRoi the absolute rectangle that defines the region of interest
* @return the absolute centroid
*/
public Point getRectangleCentroid (Rectangle absRoi);
//TODO: REMOVE getRelation ASAP
public StickRelation getRelation ();
/**
* Report the number of runs this sections contains.
*
* @return the nb of runs in the section
*/
public int getRunCount ();
/**
* Return the list of all runs in this section.
*
* @return the section runs
*/
public List<Run> getRuns ();
/**
* Return the smallest run starting coordinate, which is the
* smallest y value (ordinate) for a section of vertical runs.
*
* @return the starting coordinate of the section
*/
public int getStartCoord ();
/**
* Return the largest run stopping coordinate, which is the
* largest y value (ordinate) for a section of vertical runs.
*
* @return the stopping coordinate of the section
*/
public int getStopCoord ();
/**
* Report the containing system.
*
* @return the system (may be null)
*/
public SystemInfo getSystem ();
/**
* Return the thickness of the section, using the provided
* orientation.
*
* @return the thickness across the provided orientation.
*/
public int getThickness (Orientation orientation);
/**
* Return the total weight of the section, which is the sum of the
* weight (length) of all runs.
*
* @return the section weight
*/
public int getWeight ();
/**
* Return the next sibling section, both linked by source of
* last incoming edge.
*
* @return the next sibling or null
*/
public Section inNextSibling ();
/**
* Return the previous sibling section, both linked by source of
* first incoming edge.
*
* @return the previous sibling or null
*/
public Section inPreviousSibling ();
/**
* Check that the section at hand is a candidate section not yet
* aggregated to a recognized stick.
*
* @return true if aggregable (but not yet aggregated)
*/
public boolean isAggregable ();
/**
* Report whether this section is "fat", according to the current
* criteria and desired orientation.
*
* @return the fat flag, if any
*/
public Boolean isFat ();
/**
* Checks whether the section is already a member of a glyph.
*
* @return the result of the test
*/
public boolean isGlyphMember ();
/**
* Check that the section at hand is a member section, aggregated
* to a known glyph.
*
* @return true if member of a known glyph
*/
public boolean isKnown ();
/**
* Report whether this section has been "processed".
*
* @return the processed
*/
public boolean isProcessed ();
/**
* Reports whether this section is organized in vertical runs.
*
* @return true if vertical, false otherwise
*/
public boolean isVertical ();
/**
* Merge this section with the other provided section, which is not
* affected, and must generally be destroyed.
* TODO: rename as "include".
* It is assumed (and not checked) that the two sections are
* contiguous.
*
* @param other the other section to include into this one
*/
public void merge (Section other);
/**
* Return the next sibling section, both linked by target of
* the last outgoing edge.
*
* @return the next sibling or null
*/
public Section outNextSibling ();
/**
* Return the previous sibling section, both linked by target of
* the first outgoing edge.
*
* @return the previous sibling or null
*/
public Section outPreviousSibling ();
/**
* Add a run at the beginning rather than at the end of the
* section.
*
* @param run the new first run
*/
public void prepend (Run run);
/**
* Nullify the fat sticky attribute.
*/
public void resetFat ();
/**
* Record the current "fatness" value of this section.
*
* @param fat the fat flag
*/
public void setFat (boolean fat);
/**
* Set the position of the first run of the section.
*
* @param firstPos position of the first run, abscissa for a vertical run,
* ordinate for a horizontal run.
*/
public void setFirstPos (int firstPos);
/**
* Assign the containing glyph, if any.
*
* @param glyph the containing glyph, perhaps null
*/
public void setGlyph (Glyph glyph);
/**
* Set a flag to be used at caller's will.
*
* @param processed the processed to set
*/
public void setProcessed (boolean processed);
/**
* Assign a containing system.
*
* @param system the system to set
*/
public void setSystem (SystemInfo system);
/**
* Apply an absolute translation vector to this section.
*
* @param vector the translation vector
*/
public void translate (Point vector);
/**
* Predicate to check whether the given absolute rectangle is
* intersected by the section.
*
* @param rectangle absolute rectangle
* @return true if intersection is not empty
*/
boolean intersects (Rectangle rectangle);
}