Files
secondo/Javagui/viewer/hoese/algebras/pmregion/Face.java

192 lines
4.4 KiB
Java
Raw Normal View History

2026-01-23 17:03:45 +08:00
package viewer.hoese.algebras.pmregion;
import java.awt.Polygon;
import java.awt.geom.Area;
import java.awt.geom.Path2D;
import java.util.LinkedList;
import java.util.List;
/**
* Class Face represents a single face of a region.
* This is a polygon with optionally one or more holes.
*
* @author Florian Heinz <fh@sysv.de>
*/
public class Face {
/** The last point set when constructing a face from points */
private Point lastPoint;
/** List of segments of this face */
private List<Seg> segs = new LinkedList();
/** List of holes in this face */
private List<Face> holes = new LinkedList();
private Area _area;
/**
* Add the next point when constructing a face.
*
* @param point Next point
*/
public void addPoint(Point point) {
if (lastPoint != null) {
segs.add(new Seg(lastPoint, point));
}
lastPoint = point;
}
/**
* Close the cycle.
* Creates the last segment from the last point to the start point.
*/
public void close() {
if (segs.size() < 2) {
return;
}
Seg s = segs.get(0);
segs.add(new Seg(lastPoint, s.s));
}
/**
* Get the list of segments of this face.
*
* @return List of segments
*/
public List<Seg> getSegments() {
return segs;
}
/**
* Create a nested list of segments of the main cycle.
*
* @return Nested List of segments
*/
public NL segsToNL() {
NL ret = new NL();
for (Seg s : segs) {
NL nl2 = ret.nest();
nl2.addNr(s.s.x);
nl2.addNr(s.s.y);
}
return ret;
}
/**
* Create a Nested List representation of this face (cycle and holes)
*
* @return Nested List representation
*/
public NL toNL() {
NL ret = new NL();
ret.addNL(segsToNL());
for (Face f : holes) {
ret.addNL(f.segsToNL());
}
return ret;
}
/**
* Create a single cycle from its Nested List representation
*
* @param nl Nested List representation
* @return A Face constructed from this cycle
*/
public static Face singleFromNL(NL nl) {
Face f = new Face();
for (int i = 0; i < nl.size(); i++) {
NL n = nl.get(i);
Point p = new Point(n.get(0).getNr(), n.get(1).getNr());
f.addPoint(p);
}
f.close();
return f;
}
/**
* Create a face from its Nested List representation (cycle and holes)
*
* @param nl Nested List representation
* @return A Face (cycle and optional holes)
*/
public static Face fromNL(NL nl) {
Face f = singleFromNL(nl.get(0));
for (int i = 1; i < nl.size(); i++)
f.addHole(singleFromNL(nl.get(i)));
return f;
}
/**
* Add a new hole to this face.
*
* @param hole Hole to add
*/
public void addHole (Face hole) {
holes.add(hole);
}
/**
* Get all holes of this face.
*
* @return List of holes
*/
public List<Face> getHoles () {
return holes;
}
private Polygon p;
public boolean contains (Point point) {
if (p == null) {
p = new Polygon();
for (Seg s : segs) {
p.addPoint((int)s.s.x, (int)s.s.y);
}
}
return p.contains(point.x, point.y);
}
public boolean contains (Face f) {
return contains (f.getFirstPoint());
}
public Point getFirstPoint() {
return segs.get(0).s;
}
/**
* Constructs a displayable Area object from a face.
*
* @return The Area to display
*/
public Area getAreaObj(boolean holestep) {
if (_area != null)
return _area;
Path2D.Double path = new Path2D.Double();
if (segs.size() < 3) {
return new Area();
}
path.moveTo(segs.get(0).s.x, segs.get(0).s.y);
for (int i = 1; i < segs.size(); i++) {
path.lineTo(segs.get(i).s.x, segs.get(i).s.y);
}
path.closePath();
Area ret = new Area(path);
if (!holestep) {
for (Face h : holes) {
ret.subtract(h.getAreaObj(true));
}
}
_area = ret;
return ret;
}
public Area getAreaObj() {
return getAreaObj(false);
}
}