/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.fge.geom;
import java.awt.geom.AffineTransform;
import java.util.logging.Logger;
import org.openflexo.fge.geom.area.FGEArea;
import org.openflexo.fge.geom.area.FGEBand;
import org.openflexo.fge.geom.area.FGEEmptyArea;
import org.openflexo.fge.geom.area.FGEHalfLine;
import org.openflexo.fge.geom.area.FGEHalfPlane;
import org.openflexo.fge.geom.area.FGEPlane;
import org.openflexo.fge.graphics.FGEGraphics;
public class FGELine extends FGEAbstractLine<FGELine> {
private static final Logger logger = Logger.getLogger(FGELine.class.getPackage().getName());
public FGELine(double X1, double Y1, double X2, double Y2) {
super(X1, Y1, X2, Y2);
}
public FGELine(FGEPoint p1, FGEPoint p2) {
super(p1, p2);
}
public FGELine(FGEAbstractLine line) {
super(line.getP1(), line.getP2());
}
public FGELine() {
super();
}
public FGELine(double pA, double pB, double pC) {
super(pA, pB, pC);
}
public FGELine(FGESegment s) {
this(s.getP1(), s.getP2());
}
public FGELine(FGEHalfLine hl) {
this(hl.getP1(), hl.getP2());
}
/**
* Build vertical line containing supplied point
*
* @param pt
* @return
*/
public static FGELine makeVerticalLine(FGEPoint pt, double distance) {
return new FGELine(pt.x, pt.y, pt.x, pt.y + distance);
}
/**
* Build vertical line containing supplied point
*
* @param pt
* @return
*/
public static FGELine makeVerticalLine(FGEPoint pt) {
return makeVerticalLine(pt, 1);
}
/**
* Build horizontal line containing supplied point
*
* @param pt
* @return
*/
public static FGELine makeHorizontalLine(FGEPoint pt, double distance) {
return new FGELine(pt.x, pt.y, pt.x + distance, pt.y);
}
/**
* Build horizontal line containing supplied point
*
* @param pt
* @return
*/
public static FGELine makeHorizontalLine(FGEPoint pt) {
return makeHorizontalLine(pt, 1);
}
@Override
public boolean contains(FGEPoint p) {
return _containsPointIgnoreBounds(p);
}
@Override
public FGEPoint getNearestPoint(FGEPoint p) {
return getProjection(p);
}
/**
* Creates a new object of the same class and with the same contents as this object.
*
* @return a clone of this instance.
* @exception OutOfMemoryError
* if there is not enough memory.
* @see java.lang.Cloneable
* @since 1.2
*/
@Override
public FGELine clone() {
return (FGELine) super.clone();
}
private static FGEArea _compute_hl_hl_Intersection(FGEHalfLine hl1, FGEHalfLine hl2) {
FGEHalfPlane hp1 = hl1.getHalfPlane();
FGEHalfPlane hp2 = hl2.getHalfPlane();
System.out.println(">>>>>>>>>>>>>> HERE");
FGEArea intersect = hp1.intersect(hp2);
if (intersect instanceof FGEEmptyArea) {
return new FGEEmptyArea();
} else if (intersect instanceof FGEBand) {
return new FGESegment(hl1.getLimit(), hl2.getLimit());
}
else if (intersect.equals(hp1)) {
return hl1.clone();
} else if (intersect.equals(hp2)) {
return hl2.clone();
} else {
logger.warning("Unexpected intersection: " + intersect);
return null;
}
}
@Override
protected FGEArea computeLineIntersection(FGEAbstractLine line) {
logger.info("computeIntersection() between " + this + "\n and " + line + " overlap=" + overlap(line));
if (overlap(line)) {
return line.clone();
} else if (isParallelTo(line)) {
return new FGEEmptyArea();
} else {
FGEPoint returned;
try {
returned = getLineIntersection(line);
if (containsPoint(returned) && line.containsPoint(returned)) {
return returned;
}
} catch (ParallelLinesException e) {
// cannot happen
}
return new FGEEmptyArea();
}
}
@Override
public boolean containsLine(FGEAbstractLine l) {
if (!overlap(l)) {
return false;
}
if (!(containsPoint(l.getP1()) && containsPoint(l.getP2()))) {
return false;
}
return true;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof FGELine) {
return overlap((FGELine) obj);
}
return false;
}
@Override
public FGELine transform(AffineTransform t) {
return new FGELine(getP1().transform(t), getP2().transform(t));
}
@Override
public String toString() {
return "FGELine: (" + getP1() + "," + getP2() + ")";
}
@Override
public String getStringRepresentation() {
return toString();
}
@Override
public void paint(FGEGraphics g) {
g.useDefaultForegroundStyle();
FGERectangle bounds = g.getGraphicalRepresentation().getNormalizedBounds();
bounds.intersect(this).paint(g);
// logger.info("Paint bounds="+bounds+": "+bounds.intersect(this));
}
@Override
public FGEArea getOrthogonalPerspectiveArea(SimplifiedCardinalDirection orientation) {
if (orientation == SimplifiedCardinalDirection.NORTH) {
if (isVertical()) {
return clone();
} else {
return new FGEPlane();
}
} else if (orientation == SimplifiedCardinalDirection.SOUTH) {
if (isVertical()) {
return clone();
} else {
return new FGEPlane();
}
} else if (orientation == SimplifiedCardinalDirection.EAST) {
if (isHorizontal()) {
return clone();
} else {
return new FGEPlane();
}
} else if (orientation == SimplifiedCardinalDirection.WEST) {
if (isHorizontal()) {
return clone();
} else {
return new FGEPlane();
}
}
return null;
}
@Override
public FGELine getAnchorAreaFrom(SimplifiedCardinalDirection direction) {
return clone();
}
/**
* This area is infinite, so always return false
*/
@Override
public final boolean isFinite() {
return false;
}
/**
* This area is infinite, so always return null
*/
@Override
public final FGERectangle getEmbeddingBounds() {
return null;
}
}