292 lines
6.7 KiB
Java
292 lines
6.7 KiB
Java
/*
|
|
|
|
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
|
|
|
This file is part of C.a.R. software.
|
|
|
|
C.a.R. is a 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, version 3 of the License.
|
|
|
|
C.a.R. 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
package rene.zirkel.objects;
|
|
|
|
// file: IntersectionObject.java
|
|
|
|
import java.util.Enumeration;
|
|
|
|
import rene.util.xml.XmlWriter;
|
|
import rene.gui.Global;
|
|
import rene.zirkel.ZirkelCanvas;
|
|
import rene.zirkel.construction.Construction;
|
|
import rene.zirkel.construction.Count;
|
|
import rene.zirkel.expression.Expression;
|
|
|
|
/**
|
|
* This is the parent class of various intersection objects. Intersections are
|
|
* points. Problems are multiple intersections and restrictions to keep one of
|
|
* them away or close to some other point. The most problematic intersections
|
|
* are between objects of type PointonObject.
|
|
*
|
|
* In case of two possible intersection points, there is also the option to
|
|
* switch from one object to the other in automatic tracks. This allows to run
|
|
* through all possible states of a construction.
|
|
*
|
|
* @author Rene
|
|
*/
|
|
|
|
public class IntersectionObject extends PointObject {
|
|
protected ConstructionObject P1, P2;
|
|
private static Count N = new Count();
|
|
protected Expression Away;
|
|
protected boolean StayAway = true;
|
|
protected boolean First;
|
|
protected boolean Switched;
|
|
protected boolean Restricted;
|
|
protected boolean Alternate;
|
|
|
|
public IntersectionObject(final Construction c,
|
|
final ConstructionObject p1, final ConstructionObject p2) {
|
|
super(c, 0, 0);
|
|
Moveable = false;
|
|
P1 = p1;
|
|
P2 = p2;
|
|
updateText();
|
|
First = true;
|
|
Switched = false;
|
|
Restricted = true;
|
|
Alternate = false;
|
|
}
|
|
|
|
@Override
|
|
public String getTag() {
|
|
return "Intersection";
|
|
}
|
|
|
|
@Override
|
|
public int getN() {
|
|
return N.next();
|
|
}
|
|
|
|
@Override
|
|
public boolean nearto(final int x, final int y, final ZirkelCanvas zc) {
|
|
if (!displays(zc))
|
|
return false;
|
|
final double c = zc.col(X), r = zc.row(Y);
|
|
final int size = (int) zc.selectionSize();
|
|
Value = Math.abs(x - c) + Math.abs(y - r);
|
|
return Value <= size * 5;
|
|
}
|
|
|
|
@Override
|
|
public void updateText() {
|
|
try {
|
|
setText(text2(Global.name("text.intersection"), P1.getName(), P2
|
|
.getName()));
|
|
} catch (final Exception e) {
|
|
}
|
|
}
|
|
|
|
public void setFirst(final boolean flag) {
|
|
First = flag;
|
|
}
|
|
|
|
public boolean isFirst() {
|
|
return First;
|
|
}
|
|
|
|
@Override
|
|
public void validate() {
|
|
if (!P1.valid() || !P2.valid())
|
|
Valid = false;
|
|
else
|
|
Valid = true;
|
|
}
|
|
|
|
public void validate(final double x, final double y) {
|
|
}
|
|
|
|
@Override
|
|
public void printArgs(final XmlWriter xml) {
|
|
xml.printArg("first", P1.getName());
|
|
xml.printArg("second", P2.getName());
|
|
if (getAway() != null) {
|
|
if (StayAway)
|
|
xml.printArg("awayfrom", getAway().getName());
|
|
else
|
|
xml.printArg("closeto", getAway().getName());
|
|
}
|
|
printType(xml);
|
|
if (!Restricted)
|
|
xml.printArg("valid", "true");
|
|
if (Alternate)
|
|
xml.printArg("alternate", "true");
|
|
}
|
|
|
|
public String away() {
|
|
if (getAway() != null)
|
|
return getAway().getName();
|
|
else
|
|
return "";
|
|
}
|
|
|
|
public boolean stayAway() {
|
|
return StayAway;
|
|
}
|
|
|
|
public boolean setAway(final String s, final boolean flag) {
|
|
Away = null;
|
|
if (s.equals(""))
|
|
return true;
|
|
if (Cn == null)
|
|
return true;
|
|
Away = new Expression("@\"" + s + "\"", Cn, this);
|
|
StayAway = flag;
|
|
return getAway() != null;
|
|
}
|
|
|
|
public boolean setAway(final String s) {
|
|
return setAway(s, true);
|
|
}
|
|
|
|
@Override
|
|
public Enumeration depending() {
|
|
super.depending();
|
|
return depset(P1, P2);
|
|
}
|
|
|
|
@Override
|
|
public void translate() {
|
|
P1 = P1.getTranslation();
|
|
P2 = P2.getTranslation();
|
|
if (getAway() != null) {
|
|
setAway(getAway().getName(), StayAway);
|
|
Away.translate();
|
|
}
|
|
}
|
|
|
|
public boolean isSwitchable() {
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check, if the other intersection is already visible and defined. In this
|
|
* case, we want to keep the intersection different from the other
|
|
* intersection point.
|
|
*/
|
|
public void autoAway() {
|
|
if (!autoAway(P1, P2))
|
|
autoAway(P2, P1);
|
|
}
|
|
|
|
boolean autoAway(final ConstructionObject o1, final ConstructionObject o2) {
|
|
if (o1 instanceof CircleObject) {
|
|
final PointObject p1 = ((CircleObject) o1).getP2();
|
|
if (p1.isHidden())
|
|
return false;
|
|
if (p1.dependsOn(o2) && !nearto(p1)) {
|
|
setAway(p1.getName());
|
|
return true;
|
|
} else if (o2 instanceof CircleObject) {
|
|
final PointObject p2 = ((CircleObject) o2).getP2();
|
|
if (p2.isHidden())
|
|
return false;
|
|
if (p1 == p2 && !nearto(p1)) {
|
|
setAway(p1.getName());
|
|
return true;
|
|
}
|
|
return false;
|
|
} else if (o2 instanceof PrimitiveLineObject) {
|
|
final Enumeration en = ((PrimitiveLineObject) o2).points();
|
|
while (en.hasMoreElements()) {
|
|
final ConstructionObject oo = (ConstructionObject) en
|
|
.nextElement();
|
|
if (oo instanceof PointObject) {
|
|
final PointObject o = (PointObject) oo;
|
|
if (o.isHidden())
|
|
return false;
|
|
if (p1 == o && !nearto(p1)) {
|
|
setAway(p1.getName());
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else if (o1 instanceof TwoPointLineObject) {
|
|
final PointObject p1 = ((TwoPointLineObject) o1).getP1();
|
|
if (!p1.isHidden() && p1.dependsOn(o2) && !nearto(p1)) {
|
|
setAway(p1.getName());
|
|
return true;
|
|
}
|
|
final PointObject p2 = ((TwoPointLineObject) o1).getP2();
|
|
if (!p2.isHidden() && p2.dependsOn(o2) && !nearto(p2)) {
|
|
setAway(p2.getName());
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public void switchBack() {
|
|
if (Switched)
|
|
First = !First;
|
|
Switched = false;
|
|
}
|
|
|
|
public void doSwitch() {
|
|
Switched = !Switched;
|
|
First = !First;
|
|
}
|
|
|
|
public boolean isSwitched() {
|
|
return Switched;
|
|
}
|
|
|
|
public boolean isRestricted() {
|
|
return Restricted;
|
|
}
|
|
|
|
public void setRestricted(final boolean flag) {
|
|
Restricted = flag;
|
|
}
|
|
|
|
public PointObject getAway() {
|
|
return getPointObject(Away);
|
|
}
|
|
|
|
public void setAlternate(final boolean flag) {
|
|
Alternate = flag;
|
|
}
|
|
|
|
public boolean isAlternate() {
|
|
return Alternate;
|
|
}
|
|
|
|
/**
|
|
* Returns, if this intersection can alternate between two states, like
|
|
* CircleIntersection and LineCircleIntersection. Used by the dialog.
|
|
*/
|
|
public boolean canAlternate() {
|
|
return false;
|
|
}
|
|
|
|
public ConstructionObject getP1(){
|
|
return P1;
|
|
}
|
|
|
|
public ConstructionObject getP2(){
|
|
return P2;
|
|
}
|
|
}
|
|
|