Make first real commit: copy of CaRMetal 4.2.8
This commit is contained in:
parent
002acfc88e
commit
c312811084
1120 changed files with 226843 additions and 1 deletions
1538
rene/zirkel/objects/.#PointObject.java.1.6
Executable file
1538
rene/zirkel/objects/.#PointObject.java.1.6
Executable file
File diff suppressed because it is too large
Load diff
BIN
rene/zirkel/objects/.DS_Store
vendored
Normal file
BIN
rene/zirkel/objects/.DS_Store
vendored
Normal file
Binary file not shown.
1015
rene/zirkel/objects/AngleObject.java
Normal file
1015
rene/zirkel/objects/AngleObject.java
Normal file
File diff suppressed because it is too large
Load diff
785
rene/zirkel/objects/AreaObject.java
Normal file
785
rene/zirkel/objects/AreaObject.java
Normal file
|
|
@ -0,0 +1,785 @@
|
|||
/*
|
||||
|
||||
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: LineObject.java
|
||||
import java.awt.Rectangle;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.gui.Global;
|
||||
import rene.zirkel.ZirkelCanvas;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.construction.ConstructionException;
|
||||
import rene.zirkel.construction.Count;
|
||||
import rene.zirkel.expression.ExpressionColor;
|
||||
import rene.zirkel.expression.InvalidException;
|
||||
import rene.zirkel.graphics.MyGraphics;
|
||||
import rene.zirkel.graphics.MainGraphics;
|
||||
|
||||
public class AreaObject extends ConstructionObject implements InsideObject,
|
||||
PointonObject, MoveableObject {
|
||||
|
||||
static Count N=new Count();
|
||||
double xpoints[]=new double[3], ypoints[]=new double[3];
|
||||
double R, X, Y, A;
|
||||
public Vector V;
|
||||
boolean Filled=true;
|
||||
private PointObject preview=null;
|
||||
|
||||
public AreaObject(final Construction c, final Vector v) {
|
||||
super(c);
|
||||
V=v;
|
||||
validate();
|
||||
updateText();
|
||||
Global.getParameter("unit.area", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaults() {
|
||||
setShowName(Global.getParameter("options.area.shownames", false));
|
||||
setShowValue(Global.getParameter("options.area.showvalues", false));
|
||||
setColor(Global.getParameter("options.area.color", 0), Global.getParameter("options.area.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.area.colortype", 0));
|
||||
setFilled(Global.getParameter("options.area.filled", true));
|
||||
setSolid(Global.getParameter("options.area.solid", false));
|
||||
setHidden(Cn.Hidden);
|
||||
setObtuse(Cn.Obtuse);
|
||||
// setSolid(Cn.Solid);
|
||||
setLarge(Cn.LargeFont);
|
||||
setBold(Cn.BoldFont);
|
||||
setPartial(Cn.Partial);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetDefaults() {
|
||||
setShowName(Global.getParameter("options.area.shownames", false));
|
||||
setShowValue(Global.getParameter("options.area.showvalues", false));
|
||||
setColor(Global.getParameter("options.area.color", 0), Global.getParameter("options.area.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.area.colortype", 0));
|
||||
setFilled(Global.getParameter("options.area.filled", true));
|
||||
setSolid(Global.getParameter("options.area.solid", false));
|
||||
}
|
||||
|
||||
public void setPreviewPoint(PointObject p){
|
||||
preview=p;
|
||||
}
|
||||
public void clearPreviewPoint(){
|
||||
preview=null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Polygon";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
String Text=Global.name("text.area");
|
||||
final Enumeration en=V.elements();
|
||||
boolean first=true;
|
||||
while (en.hasMoreElements()) {
|
||||
final PointObject p=(PointObject) en.nextElement();
|
||||
if (!first) {
|
||||
Text=Text+", ";
|
||||
} else {
|
||||
Text=Text+" ";
|
||||
}
|
||||
first=false;
|
||||
Text=Text+p.getName();
|
||||
}
|
||||
setText(Text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
final Enumeration e=V.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
if (!((ConstructionObject) e.nextElement()).valid()) {
|
||||
Valid=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
int realsize=(preview==null)?V.size():V.size()+1;
|
||||
if (realsize<2) {
|
||||
Valid=false;
|
||||
return;
|
||||
}
|
||||
final Enumeration en=V.elements();
|
||||
double x=0, y=0;
|
||||
while (en.hasMoreElements()) {
|
||||
final PointObject p=(PointObject) en.nextElement();
|
||||
x+=p.getX();
|
||||
y+=p.getY();
|
||||
}
|
||||
X=x/V.size();
|
||||
Y=y/V.size();
|
||||
A=area();
|
||||
Valid=true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(final MyGraphics g, final ZirkelCanvas zc) {
|
||||
if (!Valid||mustHide(zc)) {
|
||||
return;
|
||||
}
|
||||
final int n=(preview==null)?V.size():V.size()+1;
|
||||
if (xpoints.length!=n) {
|
||||
xpoints=new double[n];
|
||||
ypoints=new double[n];
|
||||
}
|
||||
|
||||
if (visible(zc)) {
|
||||
|
||||
final Enumeration e=V.elements();
|
||||
int i=0;
|
||||
while (e.hasMoreElements()) {
|
||||
final PointObject p=(PointObject) e.nextElement();
|
||||
|
||||
xpoints[i]=zc.col(p.getX());
|
||||
ypoints[i]=zc.row(p.getY());
|
||||
if (i>0) {
|
||||
if (isStrongSelected()&&g instanceof MainGraphics) {
|
||||
((MainGraphics) g).drawMarkerLine(xpoints[i-1],
|
||||
ypoints[i-1], xpoints[i], ypoints[i]);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (preview!=null){
|
||||
xpoints[i]=zc.col(preview.getX());
|
||||
ypoints[i]=zc.row(preview.getY());
|
||||
i++;
|
||||
}
|
||||
if (i>1) {
|
||||
if (isStrongSelected()&&g instanceof MainGraphics) {
|
||||
((MainGraphics) g).drawMarkerLine(xpoints[i-1],
|
||||
ypoints[i-1], xpoints[0], ypoints[0]);
|
||||
}
|
||||
}
|
||||
|
||||
g.fillPolygon(xpoints, ypoints, n, this);
|
||||
}
|
||||
final String s=getDisplayText();
|
||||
if (!s.equals("")) {
|
||||
// if (getColorIndex() == 0 && getColorType() == THICK) {
|
||||
// g.setColor(Color.gray.brighter());
|
||||
// } else {
|
||||
// g.setColor(Color.black);
|
||||
// }
|
||||
DisplaysText=true;
|
||||
TX1=zc.col(X+XcOffset);
|
||||
TY1=zc.row(Y+YcOffset);
|
||||
setFont(g);
|
||||
drawLabel(g, s);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayValue() {
|
||||
// return ""+round(Math.abs(A), ZirkelCanvas.LengthsFactor);
|
||||
return Global.getLocaleNumber(Math.abs(A), "lengths");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
if (!Filled) {
|
||||
xml.printArg("filled", "false");
|
||||
}
|
||||
final Enumeration e=V.elements();
|
||||
int n=1;
|
||||
while (e.hasMoreElements()) {
|
||||
final ConstructionObject o=(ConstructionObject) e.nextElement();
|
||||
xml.printArg("point"+n, o.getName());
|
||||
n++;
|
||||
}
|
||||
|
||||
super.printArgs(xml);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
super.depending();
|
||||
final Enumeration e=V.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
final ConstructionObject o=(ConstructionObject) e.nextElement();
|
||||
DL.add(o);
|
||||
}
|
||||
return DL.elements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
final Enumeration e=V.elements();
|
||||
final Vector w=new Vector();
|
||||
while (e.hasMoreElements()) {
|
||||
final ConstructionObject o=(ConstructionObject) e.nextElement();
|
||||
w.addElement(o.getTranslation());
|
||||
}
|
||||
V=w;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInRect(Rectangle r, ZirkelCanvas zc) {
|
||||
final Enumeration e=V.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
final PointObject p=(PointObject) e.nextElement();
|
||||
if (!r.contains(zc.col(p.getX()), zc.row(p.getY()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int c, final int r, final ZirkelCanvas zc) {
|
||||
if (!displays(zc)) {
|
||||
return false;
|
||||
}
|
||||
return contains(zc.x(c), zc.y(r));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int c, final int r, final boolean ignorefill,
|
||||
final ZirkelCanvas zc) {
|
||||
if (!displays(zc)) {
|
||||
return false;
|
||||
}
|
||||
if (contains(zc.x(c), zc.y(r), zc.dx(zc.selectionSize()))) {
|
||||
if (ignorefill) {
|
||||
return OnBoundary;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
boolean OnBoundary;
|
||||
|
||||
public boolean contains(final double x, final double y, final double eps) {
|
||||
if (!Valid) {
|
||||
return false;
|
||||
}
|
||||
OnBoundary=false;
|
||||
final PointObject First=(PointObject) V.elementAt(0);
|
||||
PointObject P=First;
|
||||
if (Math.max(Math.abs(P.getX()-x), Math.abs(P.getY()-y))<eps) {
|
||||
OnBoundary=true;
|
||||
return true;
|
||||
}
|
||||
final Enumeration e=V.elements();
|
||||
double a=Math.atan2(P.getX()-x, P.getY()-y);
|
||||
double sum=0;
|
||||
PointObject Q;
|
||||
while (e.hasMoreElements()) {
|
||||
Q=(PointObject) e.nextElement();
|
||||
if (Math.max(Math.abs(Q.getX()-x), Math.abs(Q.getY()-y))<eps) {
|
||||
OnBoundary=true;
|
||||
return true;
|
||||
}
|
||||
final double b=Math.atan2(Q.getX()-x, Q.getY()-y);
|
||||
double d=b-a;
|
||||
if (d>Math.PI) {
|
||||
d=d-2*Math.PI;
|
||||
} else if (d<-Math.PI) {
|
||||
d=d+2*Math.PI;
|
||||
}
|
||||
if (Math.abs(Math.abs(d)-Math.PI)<0.1) {
|
||||
OnBoundary=true;
|
||||
return true;
|
||||
}
|
||||
a=b;
|
||||
P=Q;
|
||||
sum+=d;
|
||||
}
|
||||
Q=First;
|
||||
final double b=Math.atan2(Q.getX()-x, Q.getY()-y);
|
||||
double d=b-a;
|
||||
if (d>Math.PI) {
|
||||
d=d-2*Math.PI;
|
||||
} else if (d<-Math.PI) {
|
||||
d=d+2*Math.PI;
|
||||
}
|
||||
if (Math.abs(Math.abs(d)-Math.PI)<0.1) {
|
||||
OnBoundary=true;
|
||||
return true;
|
||||
}
|
||||
sum+=d;
|
||||
return Math.abs(sum)>=Math.PI/2;
|
||||
}
|
||||
|
||||
public boolean contains(final double x, final double y) {
|
||||
return contains(x, y, 1e-4);
|
||||
}
|
||||
|
||||
// This one is better than "contains" method :
|
||||
public boolean contains2(final double x, final double y) {
|
||||
if (!Valid) {
|
||||
return false;
|
||||
}
|
||||
final int npoints=V.size();
|
||||
if (npoints<=2) {
|
||||
return false;
|
||||
}
|
||||
int hits=0;
|
||||
final PointObject last=(PointObject) V.get(npoints-1);
|
||||
double lastx=last.getX();
|
||||
double lasty=last.getY();
|
||||
|
||||
double curx, cury;
|
||||
|
||||
final Enumeration e=V.elements();
|
||||
for (int i=0; i<npoints; lastx=curx, lasty=cury, i++) {
|
||||
final PointObject p=(PointObject) e.nextElement();
|
||||
curx=p.getX();
|
||||
cury=p.getY();
|
||||
|
||||
if (cury==lasty) {
|
||||
continue;
|
||||
}
|
||||
|
||||
double leftx;
|
||||
if (curx<lastx) {
|
||||
if (x>=lastx) {
|
||||
continue;
|
||||
}
|
||||
leftx=curx;
|
||||
} else {
|
||||
if (x>=curx) {
|
||||
continue;
|
||||
}
|
||||
leftx=lastx;
|
||||
}
|
||||
|
||||
double test1, test2;
|
||||
|
||||
if (cury<lasty) {
|
||||
if (y<cury||y>=lasty) {
|
||||
continue;
|
||||
}
|
||||
if (x<leftx) {
|
||||
hits++;
|
||||
continue;
|
||||
}
|
||||
test1=x-curx;
|
||||
test2=y-cury;
|
||||
} else {
|
||||
if (y<lasty||y>=cury) {
|
||||
continue;
|
||||
}
|
||||
if (x<leftx) {
|
||||
hits++;
|
||||
continue;
|
||||
}
|
||||
test1=x-lastx;
|
||||
test2=y-lasty;
|
||||
}
|
||||
|
||||
if (test1<(test2/(lasty-cury)*(lastx-curx))) {
|
||||
hits++;
|
||||
}
|
||||
}
|
||||
|
||||
return ((hits&1)!=0);
|
||||
}
|
||||
|
||||
public double area() {
|
||||
if (!Valid) {
|
||||
return -1;
|
||||
}
|
||||
final PointObject First=(PointObject) V.elementAt(0);
|
||||
PointObject P=First;
|
||||
final Enumeration e=V.elements();
|
||||
double sum=0;
|
||||
PointObject Q;
|
||||
while (e.hasMoreElements()) {
|
||||
Q=(PointObject) e.nextElement();
|
||||
sum+=(Q.getX()-X)*(P.getY()-Y)-(Q.getY()-Y)*(P.getX()-X);
|
||||
P=Q;
|
||||
}
|
||||
Q=First;
|
||||
sum+=(Q.getX()-X)*(P.getY()-Y)-(Q.getY()-Y)*(P.getX()-X);
|
||||
return sum/2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final ConstructionObject o) {
|
||||
if (!(o instanceof AreaObject)||!o.valid()) {
|
||||
return false;
|
||||
}
|
||||
final AreaObject a=(AreaObject) o;
|
||||
|
||||
final int n=V.size(), m=a.V.size();
|
||||
final PointObject p[]=new PointObject[n];
|
||||
V.copyInto(p);
|
||||
final PointObject pa[]=new PointObject[m];
|
||||
a.V.copyInto(pa);
|
||||
double x0=0, y0=0;
|
||||
for (int i=0; i<m; i++) {
|
||||
boolean r=true;
|
||||
int j=0, kj=0;
|
||||
while (true) {
|
||||
int k=i+kj;
|
||||
if (k>=m) {
|
||||
k-=m;
|
||||
}
|
||||
if (!p[j].equals(pa[k])) {
|
||||
if (j==0||!between(x0, y0, p[j].getX(), p[j].getY(), pa[k].getX(), pa[k].getY())) {
|
||||
r=false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
x0=p[j].getX();
|
||||
y0=p[j].getY();
|
||||
j++;
|
||||
}
|
||||
kj++;
|
||||
if (j>=n||kj>=m) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r&&kj>=m) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (int i=0; i<m; i++) {
|
||||
boolean r=true;
|
||||
int j=0, kj=0;
|
||||
while (true) {
|
||||
int k=i+kj;
|
||||
if (k>=m) {
|
||||
k-=m;
|
||||
}
|
||||
if (!p[n-j-1].equals(pa[k])) {
|
||||
if (j==0||!between(x0, y0, p[n-j-1].getX(), p[n-j-1].getY(), pa[k].getX(), pa[k].getY())) {
|
||||
r=false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
x0=p[n-j-1].getX();
|
||||
y0=p[n-j-1].getY();
|
||||
j++;
|
||||
}
|
||||
kj++;
|
||||
if (j>=n||kj>=m) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r&&kj>=m) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean between(final double x0, final double y0, final double x1,
|
||||
final double y1, final double x, final double y) {
|
||||
double lambda;
|
||||
if (Math.abs(x1-x0)>Math.abs(y1-y0)) {
|
||||
lambda=(x-x0)/(x1-x0);
|
||||
} else {
|
||||
lambda=(y-y0)/(y1-y0);
|
||||
}
|
||||
return Math.abs(x0+lambda*(x1-x0)-x)<1e-10&&Math.abs(y0+lambda*(y1-y0)-y)<1e-10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue() throws ConstructionException {
|
||||
if (!Valid) {
|
||||
throw new InvalidException("exception.invalid");
|
||||
} else {
|
||||
return A;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean maybeTransparent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilled(final boolean flag) {
|
||||
Filled=flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFilled() {
|
||||
return Filled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onlynearto(final int x, final int y, final ZirkelCanvas zc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void keepBaricentricCoords(final PointObject P) {
|
||||
if ((P.BarycentricCoordsInitialzed)&&(V.size()>2)) {
|
||||
final PointObject AA=(PointObject) V.get(0);
|
||||
final PointObject BB=(PointObject) V.get(1);
|
||||
final PointObject CC=(PointObject) V.get(2);
|
||||
|
||||
final double xa=AA.getX(), ya=AA.getY();
|
||||
|
||||
final double xb=BB.getX(), yb=BB.getY();
|
||||
|
||||
final double xc=CC.getX(), yc=CC.getY();
|
||||
|
||||
final double xm=xa+P.Gx*(xb-xa)+P.Gy*(xc-xa);
|
||||
final double ym=ya+P.Gx*(yb-ya)+P.Gy*(yc-ya);
|
||||
|
||||
P.move(xm, ym);
|
||||
} else {
|
||||
P.computeBarycentricCoords();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistance(final PointObject P) {
|
||||
final double x=P.getX(), y=P.getY();
|
||||
final Enumeration e=V.elements();
|
||||
PointObject p=(PointObject) e.nextElement();
|
||||
double x1=p.getX(), y1=p.getY();
|
||||
final double xstart=x1, ystart=y1;
|
||||
int count=0;
|
||||
|
||||
double xmin=x1, ymin=y1, dmin=1e20;
|
||||
while (e.hasMoreElements()) {
|
||||
p=(PointObject) e.nextElement();
|
||||
final double x2=p.getX(), y2=p.getY();
|
||||
final double dx=x2-x1, dy=y2-y1;
|
||||
final double r=dx*dx+dy*dy;
|
||||
if (r>1e-5) {
|
||||
double h=dx*(x-x1)/r+dy*(y-y1)/r;
|
||||
if (h>1) {
|
||||
h=1;
|
||||
} else if (h<0) {
|
||||
h=0;
|
||||
}
|
||||
final double xh=x1+h*dx, yh=y1+h*dy;
|
||||
final double dist=Math.sqrt((x-xh)*(x-xh)+(y-yh)*(y-yh));
|
||||
if (dist<dmin) {
|
||||
dmin=dist;
|
||||
xmin=xh;
|
||||
ymin=yh;
|
||||
}
|
||||
}
|
||||
count++;
|
||||
x1=x2;
|
||||
y1=y2;
|
||||
}
|
||||
final double x2=xstart, y2=ystart;
|
||||
final double dx=x2-x1, dy=y2-y1;
|
||||
final double r=dx*dx+dy*dy;
|
||||
if (r>1e-5) {
|
||||
double h=dx*(x-x1)/r+dy*(y-y1)/r;
|
||||
if (h>1) {
|
||||
h=1;
|
||||
} else if (h<0) {
|
||||
h=0;
|
||||
}
|
||||
final double xh=x1+h*dx, yh=y1+h*dy;
|
||||
final double dist=Math.sqrt((x-xh)*(x-xh)+(y-yh)*(y-yh));
|
||||
if (dist<dmin) {
|
||||
dmin=dist;
|
||||
xmin=xh;
|
||||
ymin=yh;
|
||||
}
|
||||
}
|
||||
final double dd=Math.sqrt((P.getX()-xmin)*(P.getX()-xmin)+(P.getY()-ymin)*(P.getY()-ymin));
|
||||
return (int) Math.round(dd*Cn.getPixel());
|
||||
}
|
||||
|
||||
public void project(final PointObject P) {
|
||||
final double x=P.getX(), y=P.getY();
|
||||
final Enumeration e=V.elements();
|
||||
PointObject p=(PointObject) e.nextElement();
|
||||
double x1=p.getX(), y1=p.getY();
|
||||
final double xstart=x1, ystart=y1;
|
||||
int count=0;
|
||||
|
||||
double xmin=x1, ymin=y1, dmin=1e20, hmin=0;
|
||||
while (e.hasMoreElements()) {
|
||||
p=(PointObject) e.nextElement();
|
||||
final double x2=p.getX(), y2=p.getY();
|
||||
final double dx=x2-x1, dy=y2-y1;
|
||||
final double r=dx*dx+dy*dy;
|
||||
if (r>1e-5) {
|
||||
double h=dx*(x-x1)/r+dy*(y-y1)/r;
|
||||
if (h>1) {
|
||||
h=1;
|
||||
} else if (h<0) {
|
||||
h=0;
|
||||
}
|
||||
final double xh=x1+h*dx, yh=y1+h*dy;
|
||||
final double dist=Math.sqrt((x-xh)*(x-xh)+(y-yh)*(y-yh));
|
||||
if (dist<dmin) {
|
||||
dmin=dist;
|
||||
xmin=xh;
|
||||
ymin=yh;
|
||||
hmin=count+h;
|
||||
}
|
||||
}
|
||||
count++;
|
||||
x1=x2;
|
||||
y1=y2;
|
||||
}
|
||||
final double x2=xstart, y2=ystart;
|
||||
final double dx=x2-x1, dy=y2-y1;
|
||||
final double r=dx*dx+dy*dy;
|
||||
if (r>1e-5) {
|
||||
double h=dx*(x-x1)/r+dy*(y-y1)/r;
|
||||
if (h>1) {
|
||||
h=1;
|
||||
} else if (h<0) {
|
||||
h=0;
|
||||
}
|
||||
final double xh=x1+h*dx, yh=y1+h*dy;
|
||||
final double dist=Math.sqrt((x-xh)*(x-xh)+(y-yh)*(y-yh));
|
||||
if (dist<dmin) {
|
||||
dmin=dist;
|
||||
xmin=xh;
|
||||
ymin=yh;
|
||||
hmin=count+h;
|
||||
}
|
||||
}
|
||||
P.move(xmin, ymin);
|
||||
P.setA(hmin);
|
||||
}
|
||||
|
||||
public void project(final PointObject P, final double alpha) {
|
||||
final int i=(int) Math.floor(alpha);
|
||||
final double h=alpha-i;
|
||||
if (i<0||i>=V.size()) {
|
||||
project(P);
|
||||
return;
|
||||
}
|
||||
final PointObject P1=(PointObject) V.elementAt(i);
|
||||
PointObject P2;
|
||||
if (i==V.size()-1) {
|
||||
P2=(PointObject) V.elementAt(0);
|
||||
} else {
|
||||
P2=(PointObject) V.elementAt(i+1);
|
||||
}
|
||||
P.setXY(P1.getX()+h*(P2.getX()-P1.getX()), P1.getY()+h*(P2.getY()-P1.getY()));
|
||||
}
|
||||
|
||||
public double containsInside(final PointObject P) {
|
||||
final boolean inside=contains2(P.getX(), P.getY());
|
||||
if (inside&&OnBoundary) {
|
||||
return 0.5;
|
||||
} else if (inside) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean keepInside(final PointObject P) {
|
||||
keepBaricentricCoords(P);
|
||||
if (contains2(P.getX(), P.getY())) {
|
||||
return true;
|
||||
}
|
||||
project(P);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void dragTo(final double x, final double y) {
|
||||
final Enumeration e=V.elements();
|
||||
int i=0;
|
||||
while (e.hasMoreElements()) {
|
||||
final PointObject p=(PointObject) e.nextElement();
|
||||
p.move(xd[i]+(x-x1), yd[i]+(y-y1));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(final double x, final double y) {
|
||||
}
|
||||
|
||||
public boolean moveable() {
|
||||
if (V==null) {
|
||||
return false;
|
||||
}
|
||||
final Enumeration e=V.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
if (!((PointObject) e.nextElement()).moveable()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
double xd[], yd[], x1, y1;
|
||||
|
||||
public void startDrag(final double x, final double y) {
|
||||
if (xd==null||xd.length!=V.size()) {
|
||||
xd=new double[V.size()];
|
||||
yd=new double[V.size()];
|
||||
}
|
||||
final Enumeration e=V.elements();
|
||||
int i=0;
|
||||
while (e.hasMoreElements()) {
|
||||
final PointObject p=(PointObject) e.nextElement();
|
||||
xd[i]=p.getX();
|
||||
yd[i]=p.getY();
|
||||
i++;
|
||||
}
|
||||
x1=x;
|
||||
y1=y;
|
||||
}
|
||||
|
||||
public double getOldX() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double getOldY() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void snap(final ZirkelCanvas zc) {
|
||||
if (moveable()) {
|
||||
final Enumeration e=V.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
final PointObject p=(PointObject) e.nextElement();
|
||||
p.snap(zc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canInteresectWith(final ConstructionObject o) {
|
||||
if (o instanceof PointonObject) {
|
||||
final ConstructionObject line=(ConstructionObject) o;
|
||||
final Enumeration e=V.elements();
|
||||
{
|
||||
final PointObject P=(PointObject) e.nextElement();
|
||||
if (line.contains(P)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void repulse(final PointObject P) {
|
||||
project(P);
|
||||
}
|
||||
}
|
||||
118
rene/zirkel/objects/AxisFunctionIntersectionObject.java
Normal file
118
rene/zirkel/objects/AxisFunctionIntersectionObject.java
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
|
||||
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: LineCircleIntersectionObject.java
|
||||
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.zirkel.construction.Construction;
|
||||
|
||||
public class AxisFunctionIntersectionObject extends IntersectionObject {
|
||||
public AxisFunctionIntersectionObject(final Construction c,
|
||||
final AxisObject P1, final FunctionObject P2, final boolean first) {
|
||||
super(c, P1, P2);
|
||||
First = first;
|
||||
validate();
|
||||
}
|
||||
|
||||
// public void updateCircleDep ()
|
||||
// { ((QuadricObject)P2).addDep(this);
|
||||
// ((PrimitiveLineObject)P1).addDep(this);
|
||||
// }
|
||||
|
||||
// public void validate ()
|
||||
// { boolean oldvalid=Valid;
|
||||
// if (!P1.valid() || !P2.valid()) Valid=false;
|
||||
// else Valid=true;
|
||||
// if (!Valid) return;
|
||||
//
|
||||
// Coordinates c=AxisObject.intersect(
|
||||
// (PrimitiveLineObject)P1,(FunctionObject)P2);
|
||||
//
|
||||
// if (c==null)
|
||||
// { if (oldvalid && getConstruction().shouldSwitch())
|
||||
// { doSwitch();
|
||||
// if (!getConstruction().noteSwitch()) Switched=false;
|
||||
// }
|
||||
// else if (oldvalid && Alternate && Away==null &&
|
||||
// getConstruction().canAlternate())
|
||||
// { First=!First;
|
||||
// }
|
||||
// Valid=false; return;
|
||||
// }
|
||||
// double X1,Y1;
|
||||
// if (getAway()!=null)
|
||||
// { double x=getAway().getX(),y=getAway().getY();
|
||||
// double r=(x-c.X)*(x-c.X)+(y-c.Y)*(y-c.Y);
|
||||
// double r1=(x-c.X1)*(x-c.X1)+(y-c.Y1)*(y-c.Y1);
|
||||
// boolean flag=(r>r1);
|
||||
// if (!StayAway) flag=!flag;
|
||||
// if (flag)
|
||||
// {
|
||||
// setXY(c.X,c.Y);
|
||||
// X1=c.X1; Y1=c.Y1;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// setXY(c.X1,c.Y1);
|
||||
// X1=c.X; Y1=c.Y;
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// { if (First) { setXY(c.X,c.Y); X1=c.X1; Y1=c.Y1; }
|
||||
// else { setXY(c.X1,c.Y1); X1=c.X; Y1=c.Y; }
|
||||
// }
|
||||
// if (Restricted)
|
||||
// {
|
||||
//
|
||||
// if (!((PrimitiveLineObject)P1).contains(X,Y)) {
|
||||
// if (!((PrimitiveLineObject)P1).contains(X1,Y1)){
|
||||
// Valid=false;
|
||||
// }else{
|
||||
// setXY(X1,Y1);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
super.printArgs(xml);
|
||||
if (First)
|
||||
xml.printArg("which", "first");
|
||||
else
|
||||
xml.printArg("which", "second");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSwitchable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAlternate() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
183
rene/zirkel/objects/AxisObject.java
Normal file
183
rene/zirkel/objects/AxisObject.java
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
|
||||
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: SegmentObject.java
|
||||
import java.util.Enumeration;
|
||||
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.zirkel.ZirkelCanvas;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.graphics.MyGraphics;
|
||||
|
||||
public class AxisObject extends PrimitiveLineObject {
|
||||
|
||||
public AxisObject(final Construction c, final boolean xaxis) {
|
||||
super(c, (xaxis) ? "xAxis" : "yAxis");
|
||||
|
||||
X1 = 0;
|
||||
Y1 = 0;
|
||||
if (xaxis) {
|
||||
DX = 1;
|
||||
DY = 0;
|
||||
|
||||
} else {
|
||||
DX = 0;
|
||||
DY = 1;
|
||||
}
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName() {
|
||||
|
||||
// if (DX==1) {
|
||||
// Name="xaxis"+getN();
|
||||
// } else {
|
||||
// Name="yaxis"+getN();
|
||||
// }
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int c, final int r, final ZirkelCanvas zc) {
|
||||
if (!displays(zc)) {
|
||||
return false;
|
||||
}
|
||||
if (!zc.getAxis_show()) {
|
||||
return false;
|
||||
}
|
||||
// compute point at c,r
|
||||
final double x = zc.x(c), y = zc.y(r);
|
||||
// compute distance from x,y
|
||||
final double d = (x - X1) * DY - (y - Y1) * DX;
|
||||
// scale in screen coordinates
|
||||
Value = Math.abs(zc.col(zc.minX() + d) - zc.col(zc.minX()));
|
||||
return Value < zc.selectionSize() * 2;
|
||||
}
|
||||
|
||||
// public static Coordinates intersect(PrimitiveLineObject l, FunctionObject
|
||||
// q) {
|
||||
//
|
||||
//
|
||||
//
|
||||
// return new Coordinates(0, 0);
|
||||
// }
|
||||
|
||||
// public String getTag() {
|
||||
// return "Axis";
|
||||
// }
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
if (DX == 1) {
|
||||
xml.printArg("xaxis", "true");
|
||||
} else {
|
||||
xml.printArg("yaxis", "true");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
DL.reset();
|
||||
|
||||
return DL.elements();
|
||||
}
|
||||
|
||||
public double getLength() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
P1 = (PointObject) P1.getTranslation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(final PointObject p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(final MyGraphics g, final ZirkelCanvas zc) {
|
||||
if (!Valid || mustHide(zc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if (isStrongSelected()&&g instanceof MyGraphics13) {
|
||||
// ((MyGraphics13)
|
||||
// g).drawMarkerLine(zc.col(-5),zc.row(1),zc.col(5),zc.row(1));
|
||||
// }
|
||||
|
||||
if (zc.getAxis_show()) {
|
||||
if (indicated()) {
|
||||
g.setColor(this);
|
||||
if (DX == 1) {
|
||||
g.drawLine(0, zc.row(0), zc.IW, zc.row(0), this);
|
||||
} else {
|
||||
g.drawLine(zc.col(0), 0, zc.col(0), zc.IH, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
if (DX == 1) {
|
||||
setText("X axis");
|
||||
} else {
|
||||
setText("Y axis");
|
||||
}
|
||||
}
|
||||
|
||||
public void dragTo(final double x, final double y) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(final double x, final double y) {
|
||||
}
|
||||
|
||||
public boolean moveable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
double x1, y1, x2, y2, x3, y3;
|
||||
|
||||
public void startDrag(final double x, final double y) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void snap(final ZirkelCanvas zc) {
|
||||
|
||||
}
|
||||
|
||||
public double getOldX() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double getOldY() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
104
rene/zirkel/objects/Circle3Object.java
Normal file
104
rene/zirkel/objects/Circle3Object.java
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
|
||||
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: Circle3Object.java
|
||||
|
||||
import java.util.Enumeration;
|
||||
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.gui.Global;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.construction.ConstructionException;
|
||||
import rene.zirkel.expression.InvalidException;
|
||||
|
||||
public class Circle3Object extends PrimitiveCircleObject {
|
||||
protected PointObject P1, P2;
|
||||
|
||||
public Circle3Object(final Construction c, final PointObject p1,
|
||||
final PointObject p2, final PointObject p3) {
|
||||
super(c, p3);
|
||||
P1 = p1;
|
||||
P2 = p2;
|
||||
validate();
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Circle3";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
setText(text3(Global.name("text.circle3"), M.getName(), P1.getName(),
|
||||
P2.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
super.validate();
|
||||
if (!M.valid() || !P1.valid() || !P2.valid()) {
|
||||
Valid = false;
|
||||
return;
|
||||
} else {
|
||||
Valid = true;
|
||||
X = M.getX();
|
||||
Y = M.getY();
|
||||
// compute normalized vector in the direction of the line:
|
||||
final double DX = P2.getX() - P1.getX(), DY = P2.getY() - P1.getY();
|
||||
R = Math.sqrt(DX * DX + DY * DY);
|
||||
if (R < 0) {
|
||||
R = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
xml.printArg("from", P1.getName());
|
||||
xml.printArg("to", P2.getName());
|
||||
super.printArgs(xml);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue() throws ConstructionException {
|
||||
if (!Valid)
|
||||
throw new InvalidException("exception.invalid");
|
||||
else
|
||||
return R;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
super.depending();
|
||||
return depset(P1, P2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
P1 = (PointObject) P1.getTranslation();
|
||||
P2 = (PointObject) P2.getTranslation();
|
||||
super.translate();
|
||||
}
|
||||
|
||||
}
|
||||
202
rene/zirkel/objects/CircleIntersectionObject.java
Normal file
202
rene/zirkel/objects/CircleIntersectionObject.java
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
|
||||
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: CircleIntersectionObject.java
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.structures.Coordinates;
|
||||
|
||||
public class CircleIntersectionObject extends IntersectionObject {
|
||||
|
||||
public CircleIntersectionObject(final Construction c,
|
||||
final PrimitiveCircleObject P1, final PrimitiveCircleObject P2,
|
||||
final boolean first) {
|
||||
super(c, P1, P2);
|
||||
First=first;
|
||||
validate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCircleDep() {
|
||||
((PrimitiveCircleObject) P1).addDep(this);
|
||||
((PrimitiveCircleObject) P2).addDep(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
|
||||
// System.out.println(getName()+":"+First);
|
||||
|
||||
|
||||
final boolean oldvalid=Valid;
|
||||
if (!P1.valid()||!P2.valid()) {
|
||||
Valid=false;
|
||||
} else {
|
||||
Valid=true;
|
||||
}
|
||||
if (!Valid) {
|
||||
return;
|
||||
}
|
||||
final Coordinates c=PrimitiveCircleObject.intersect(
|
||||
(PrimitiveCircleObject) P1, (PrimitiveCircleObject) P2);
|
||||
if (c==null) {
|
||||
if (oldvalid&&getConstruction().shouldSwitch()) {
|
||||
doSwitch();
|
||||
if (!getConstruction().noteSwitch()) {
|
||||
Switched=false;
|
||||
}
|
||||
} else if (oldvalid&&Alternate&&Away==null
|
||||
&&getConstruction().canAlternate()) {
|
||||
First=!First;
|
||||
}
|
||||
Valid=false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Gestion des intersections droite/cercle (droite au sens large) en mode DP :
|
||||
if (((P1.isDPLineOrSegmentObject())&&(P2.isDPCircleObject()))
|
||||
||(((P2.isDPLineOrSegmentObject())&&(P1.isDPCircleObject())))) {
|
||||
|
||||
// arc doit être la droite ou le segment hyperbolique :
|
||||
PrimitiveCircleObject arc=(PrimitiveCircleObject) ((P1.isDPLineOrSegmentObject())?P1:P2);
|
||||
|
||||
// Calcul de la coord z du produit vectoriel OStart ^ OEnd :
|
||||
Double prod1=(arc.getStart().getX()-arc.getX())*(arc.getEnd().getY()-arc.getY())
|
||||
-(arc.getStart().getY()-arc.getY())*(arc.getEnd().getX()-arc.getX());
|
||||
|
||||
// Calcul de la coord z du produit vectoriel OI ^ OJ (I et J sont les deux pts
|
||||
// d'intersection calculés) :
|
||||
Double prod2=(c.X-arc.getX())*(c.Y1-arc.getY())-(c.Y-arc.getY())*(c.X1-arc.getX());
|
||||
|
||||
|
||||
if (prod1*prod2>0) {
|
||||
if (First) {
|
||||
setXY(c.X, c.Y);
|
||||
} else {
|
||||
setXY(c.X1, c.Y1);
|
||||
}
|
||||
} else {
|
||||
if (First) {
|
||||
setXY(c.X1, c.Y1);
|
||||
} else {
|
||||
setXY(c.X, c.Y);
|
||||
}
|
||||
}
|
||||
|
||||
if (Restricted) {
|
||||
if (!(((PrimitiveCircleObject) P1).getStart()==this||((PrimitiveCircleObject) P1).getEnd()==this)
|
||||
&&!((PrimitiveCircleObject) P1).contains(X, Y)) {
|
||||
Valid=false;
|
||||
}
|
||||
if (!(((PrimitiveCircleObject) P2).getStart()==this||((PrimitiveCircleObject) P2).getEnd()==this)
|
||||
&&!((PrimitiveCircleObject) P2).contains(X, Y)) {
|
||||
Valid=false;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Gestion des intersections droite/droite (droite au sens large) en mode DP :
|
||||
else if((P1.isDPLineOrSegmentObject())&&(P2.isDPLineOrSegmentObject())) {
|
||||
PrimitiveCircleObject Hz=Cn.getHZ();
|
||||
if ((Hz!=P1)&&(Hz!=P2)) {
|
||||
final double r=(c.X)*(c.X)+(c.Y)*(c.Y);
|
||||
final double r1=(c.X1)*(c.X1)+(c.Y1)*(c.Y1);
|
||||
final double R=Hz.getR()*Hz.getR();
|
||||
if ((r>R)||(r1>R)) {
|
||||
if (r<R) {
|
||||
setXY(c.X, c.Y);
|
||||
} else {
|
||||
setXY(c.X1, c.Y1);
|
||||
}
|
||||
if (Restricted) {
|
||||
if (!(((PrimitiveCircleObject) P1).getStart()==this||((PrimitiveCircleObject) P1).getEnd()==this)
|
||||
&&!((PrimitiveCircleObject) P1).contains(X, Y)) {
|
||||
Valid=false;
|
||||
}
|
||||
if (!(((PrimitiveCircleObject) P2).getStart()==this||((PrimitiveCircleObject) P2).getEnd()==this)
|
||||
&&!((PrimitiveCircleObject) P2).contains(X, Y)) {
|
||||
Valid=false;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
final PointObject oa=getAway();
|
||||
if (oa!=null) {
|
||||
final double x=oa.getX(), y=oa.getY();
|
||||
final double r=(x-c.X)*(x-c.X)+(y-c.Y)*(y-c.Y);
|
||||
final double r1=(x-c.X1)*(x-c.X1)+(y-c.Y1)*(y-c.Y1);
|
||||
boolean flag=(r>r1);
|
||||
if (!StayAway) {
|
||||
flag=!flag;
|
||||
}
|
||||
if (flag) {
|
||||
|
||||
setXY(c.X, c.Y);
|
||||
} else {
|
||||
|
||||
setXY(c.X1, c.Y1);
|
||||
}
|
||||
} else {
|
||||
if (First) {
|
||||
setXY(c.X, c.Y);
|
||||
} else {
|
||||
setXY(c.X1, c.Y1);
|
||||
}
|
||||
}
|
||||
if (Restricted) {
|
||||
if (!(((PrimitiveCircleObject) P1).getStart()==this||((PrimitiveCircleObject) P1).getEnd()==this)
|
||||
&&!((PrimitiveCircleObject) P1).contains(X, Y)) {
|
||||
Valid=false;
|
||||
}
|
||||
if (!(((PrimitiveCircleObject) P2).getStart()==this||((PrimitiveCircleObject) P2).getEnd()==this)
|
||||
&&!((PrimitiveCircleObject) P2).contains(X, Y)) {
|
||||
Valid=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
super.printArgs(xml);
|
||||
if (First) {
|
||||
xml.printArg("which", "first");
|
||||
} else {
|
||||
xml.printArg("which", "second");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSwitchable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAlternate() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
272
rene/zirkel/objects/CircleObject.java
Normal file
272
rene/zirkel/objects/CircleObject.java
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
|
||||
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: CircleObject.java
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import rene.dialogs.Warning;
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.gui.Global;
|
||||
import rene.zirkel.ZirkelCanvas;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.construction.ConstructionException;
|
||||
import rene.zirkel.expression.Expression;
|
||||
import rene.zirkel.expression.InvalidException;
|
||||
|
||||
public class CircleObject extends PrimitiveCircleObject implements
|
||||
MoveableObject {
|
||||
protected PointObject P2;
|
||||
boolean Fixed = false;
|
||||
Expression E;
|
||||
boolean ExpressionFailed;
|
||||
boolean Ellipse = false;
|
||||
|
||||
public CircleObject(final Construction c, final PointObject p1,
|
||||
final PointObject p2) {
|
||||
super(c, p1);
|
||||
P2 = p2;
|
||||
validate();
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Circle";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
if (Fixed) {
|
||||
if (E == null) {
|
||||
setText(text3(Global.name("text.circle.fixed"), M.getName(), P2
|
||||
.getName(), "" + round(R)));
|
||||
} else {
|
||||
setText(text3(Global.name("text.circle.fixed"), M.getName(), P2
|
||||
.getName(), "\"" + E.toString() + "\""));
|
||||
}
|
||||
} else {
|
||||
setText(text2(Global.name("text.circle"), M.getName(), P2.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
super.validate();
|
||||
ExpressionFailed = false;
|
||||
if (!M.valid() || !P2.valid()) {
|
||||
Valid = false;
|
||||
return;
|
||||
} else {
|
||||
Valid = true;
|
||||
X = M.getX();
|
||||
Y = M.getY();
|
||||
final double X2 = P2.getX(), Y2 = P2.getY();
|
||||
// compute normalized vector in the direction of the line:
|
||||
final double DX = X2 - X, DY = Y2 - Y;
|
||||
R = Math.sqrt(DX * DX + DY * DY);
|
||||
if (Fixed) {
|
||||
if (!P2.moveableBy(this)) {
|
||||
Fixed = false;
|
||||
} else {
|
||||
try {
|
||||
double FixR = E.getValue();
|
||||
if (FixR < 0) {
|
||||
FixR = 0;
|
||||
}
|
||||
if (R < 1e-10) {
|
||||
P2.move(X + FixR, Y);
|
||||
} else {
|
||||
P2.move(X + DX * FixR / R, Y + DY * FixR / R);
|
||||
}
|
||||
R = FixR;
|
||||
P2.movedBy(this);
|
||||
} catch (final Exception e) {
|
||||
R = 0;
|
||||
P2.move(X, Y);
|
||||
ExpressionFailed = true;
|
||||
Valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
xml.printArg("through", P2.getName());
|
||||
if (Fixed && E != null) {
|
||||
xml.printArg("fixed", E.toString());
|
||||
}
|
||||
super.printArgs(xml);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canFix() {
|
||||
return /* M.moveableBy(this) || */P2.moveableBy(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fixed() {
|
||||
return Fixed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFixed(final boolean flag, final String s)
|
||||
throws ConstructionException {
|
||||
if (!flag || s.equals("")) {
|
||||
Fixed = false;
|
||||
E = null;
|
||||
} else {
|
||||
E = new Expression(s, getConstruction(), this);
|
||||
if (!E.isValid()) {
|
||||
throw new ConstructionException(E.getErrorText());
|
||||
}
|
||||
Fixed = true;
|
||||
}
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int c, final int r, final ZirkelCanvas zc) {
|
||||
if (ExpressionFailed && M.valid()) {
|
||||
return M.nearto(c, r, zc);
|
||||
}
|
||||
return super.nearto(c, r, zc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isValidFix() {
|
||||
return E != null && E.isValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCircleDep() {
|
||||
addDep(P2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
super.translate();
|
||||
P2 = (PointObject) P2.getTranslation();
|
||||
try {
|
||||
setFixed(Fixed, E.toString());
|
||||
E.translate();
|
||||
} catch (final Exception e) {
|
||||
Fixed = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStringLength() {
|
||||
if (E != null) {
|
||||
return E.toString();
|
||||
} else {
|
||||
return "" + roundDisplay(R);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue() throws ConstructionException {
|
||||
if (!Valid) {
|
||||
throw new InvalidException("exception.invalid");
|
||||
} else {
|
||||
return R;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
super.depending();
|
||||
if (!Fixed || E == null) {
|
||||
return depset(P2);
|
||||
} else {
|
||||
depset(P2);
|
||||
final Enumeration e = E.getDepList().elements();
|
||||
while (e.hasMoreElements()) {
|
||||
DL.add((ConstructionObject) e.nextElement());
|
||||
}
|
||||
return DL.elements();
|
||||
}
|
||||
}
|
||||
|
||||
public void setP1P2(final PointObject p1, final PointObject p2) {
|
||||
M = p1;
|
||||
P2 = p2;
|
||||
}
|
||||
|
||||
public PointObject getP2() {
|
||||
return P2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(final PointObject p) {
|
||||
return p == P2;
|
||||
}
|
||||
|
||||
public void dragTo(final double x, final double y) {
|
||||
|
||||
M.move(x1 + (x - x3), y1 + (y - y3));
|
||||
P2.move(x2 + (x - x3), y2 + (y - y3));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(final double x, final double y) {
|
||||
}
|
||||
|
||||
public boolean moveable() {
|
||||
if (!Fixed && M.moveable() && P2.moveable()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
double x1, y1, x2, y2, x3, y3;
|
||||
|
||||
public void startDrag(final double x, final double y) {
|
||||
x1 = M.getX();
|
||||
y1 = M.getY();
|
||||
x2 = P2.getX();
|
||||
y2 = P2.getY();
|
||||
x3 = x;
|
||||
y3 = y;
|
||||
}
|
||||
|
||||
public double getOldX() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double getOldY() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void snap(final ZirkelCanvas zc) {
|
||||
if (moveable()) {
|
||||
M.snap(zc);
|
||||
P2.snap(zc);
|
||||
}
|
||||
}
|
||||
}
|
||||
2345
rene/zirkel/objects/ConstructionObject.java
Normal file
2345
rene/zirkel/objects/ConstructionObject.java
Normal file
File diff suppressed because it is too large
Load diff
31
rene/zirkel/objects/DriverObject.java
Normal file
31
rene/zirkel/objects/DriverObject.java
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
|
||||
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;
|
||||
|
||||
public interface DriverObject {
|
||||
public void clearChanges();
|
||||
|
||||
public boolean somethingChanged();
|
||||
|
||||
public boolean isDriverObject();
|
||||
|
||||
}
|
||||
464
rene/zirkel/objects/EquationXYObject.java
Normal file
464
rene/zirkel/objects/EquationXYObject.java
Normal file
|
|
@ -0,0 +1,464 @@
|
|||
/*
|
||||
|
||||
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;
|
||||
|
||||
import eric.bar.JPropertiesBar;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
import rene.gui.Global;
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.zirkel.ZirkelCanvas;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.construction.ConstructionException;
|
||||
import rene.zirkel.expression.Expression;
|
||||
import rene.zirkel.expression.InvalidException;
|
||||
import rene.zirkel.graphics.MyGraphics;
|
||||
import rene.zirkel.structures.Coordinates;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author erichake
|
||||
*/
|
||||
public class EquationXYObject extends ConstructionObject implements
|
||||
PointonObject {
|
||||
|
||||
Vector V=new Vector();
|
||||
// Number of horizontal divisions for the full zero search algorithm :
|
||||
int Dhor=100;
|
||||
// canvas left,top,width,height :
|
||||
double Wl=0, Wt=0, Ww=0, Wh=0;
|
||||
Construction C;
|
||||
Expression EY=null;
|
||||
double X[]={0, 0};
|
||||
String Var[]={"x", "y"};
|
||||
|
||||
public EquationXYObject(final Construction c, final String eq) {
|
||||
super(c);
|
||||
EY=new Expression(eq, c, this, Var);
|
||||
updateText();
|
||||
C=c;
|
||||
}
|
||||
|
||||
public EquationXYObject(final Construction c, final String eq, final int d) {
|
||||
this(c, eq);
|
||||
Dhor=d;
|
||||
}
|
||||
|
||||
public int getDhor() {
|
||||
return Dhor;
|
||||
}
|
||||
|
||||
public void setDhor(final int newDHor) {
|
||||
Dhor=newDHor;
|
||||
compute();
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaults() {
|
||||
setShowName(Global.getParameter("options.locus.shownames", false));
|
||||
setShowValue(Global.getParameter("options.locus.showvalues", false));
|
||||
setColor(Global.getParameter("options.locus.color", 0));
|
||||
setColorType(Global.getParameter("options.locus.colortype", 0));
|
||||
setFilled(Global.getParameter("options.locus.filled", false));
|
||||
setHidden(Cn.Hidden);
|
||||
setObtuse(Cn.Obtuse);
|
||||
setSolid(Cn.Solid);
|
||||
setLarge(Cn.LargeFont);
|
||||
setBold(Cn.BoldFont);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetDefaults() {
|
||||
setShowName(Global.getParameter("options.locus.shownames", false));
|
||||
setShowValue(Global.getParameter("options.locus.showvalues", false));
|
||||
setColor(Global.getParameter("options.locus.color", 0));
|
||||
setColorType(Global.getParameter("options.locus.colortype", 0));
|
||||
setFilled(Global.getParameter("options.locus.filled", false));
|
||||
}
|
||||
|
||||
public void setEquation(final String eq, final ZirkelCanvas zc) {
|
||||
EY=new Expression(eq, C, this, Var);
|
||||
compute();
|
||||
updateText();
|
||||
|
||||
}
|
||||
|
||||
public double getValue(final String var) throws ConstructionException {
|
||||
if (!Valid) {
|
||||
throw new InvalidException("exception.invalid");
|
||||
}
|
||||
|
||||
return (var.equals("x"))?X[0]:X[1];
|
||||
|
||||
}
|
||||
|
||||
public double evaluateF(final double x, final double y)
|
||||
throws ConstructionException {
|
||||
X[0]=x;
|
||||
X[1]=y;
|
||||
try {
|
||||
return EY.getValue();
|
||||
} catch (final Exception e) {
|
||||
throw new ConstructionException("");
|
||||
}
|
||||
}
|
||||
|
||||
public void compute() {
|
||||
Wl=C.getX()-C.getW();
|
||||
Wt=C.getY()-C.getH()/2;
|
||||
Ww=2*C.getW();
|
||||
Wh=C.getH();
|
||||
searchZerosSegments();
|
||||
}
|
||||
|
||||
public void searchZerosSegments() {
|
||||
V.clear();
|
||||
final double dx=Ww/Dhor;
|
||||
final double dy=dx*Math.sqrt(3)/2;
|
||||
final int xn=Dhor+2;
|
||||
final int yn=(int) (Wh/dy)+1;
|
||||
|
||||
final double[] x=new double[xn+1];
|
||||
final double[] y=new double[yn+1];
|
||||
final double[][] z=new double[xn+1][yn+1];
|
||||
|
||||
for (int i=0; i<=xn; i++) {
|
||||
x[i]=Wl-dx+i*dx;
|
||||
}
|
||||
for (int j=0; j<=yn; j++) {
|
||||
y[j]=Wt+j*dy;
|
||||
}
|
||||
for (int i=0; i<=xn; i++) {
|
||||
for (int j=0; j<=yn; j++) {
|
||||
xv[0]=x[i];
|
||||
xv[1]=y[j];
|
||||
if (j%2==0) {
|
||||
xv[0]+=dx/2;
|
||||
}
|
||||
try {
|
||||
z[i][j]=evaluateF(xv[0], xv[1]);
|
||||
} catch (final Exception e) {
|
||||
z[i][j]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i=0; i<=xn-1; i++) {
|
||||
for (int j=0; j<=yn-1; j++) {
|
||||
if (j%2==0) {
|
||||
searchOneZerosSegment(V, x[i]+dx/2, y[j], z[i][j],
|
||||
x[i], y[j+1], z[i][j+1], x[i+1], y[j+1],
|
||||
z[i+1][j+1]);
|
||||
searchOneZerosSegment(V, x[i]+dx/2, y[j], z[i][j],
|
||||
x[i+1]+dx/2, y[j], z[i+1][j], x[i+1],
|
||||
y[j+1], z[i+1][j+1]);
|
||||
} else {
|
||||
searchOneZerosSegment(V, x[i], y[j], z[i][j], x[i+1],
|
||||
y[j], z[i+1][j], x[i]+dx/2, y[j+1],
|
||||
z[i][j+1]);
|
||||
searchOneZerosSegment(V, x[i+1], y[j], z[i+1][j],
|
||||
x[i+1]-dx/2, y[j+1], z[i][j+1], x[i+1]+dx/2, y[j+1], z[i+1][j+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void searchOneZerosSegment(final Vector v, final double x1,
|
||||
final double y1, final double z1, final double x2, final double y2,
|
||||
final double z2, final double x3, final double y3, final double z3) {
|
||||
if (z1*z2<0) {
|
||||
double l1=z2/(z2-z1);
|
||||
l1=fix(x1, y1, z1, x2, y2, z2, l1);
|
||||
final double m1=1-l1;
|
||||
if (z1*z3<0) {
|
||||
double l2=z3/(z3-z1);
|
||||
l2=fix(x1, y1, z1, x3, y3, z3, l2);
|
||||
final double m2=1-l2;
|
||||
v.add(new Coordinates(l1*x1+m1*x2, l1*y1+m1*y2, l2*x1+m2*x3, l2*y1+m2*y3));
|
||||
} else {
|
||||
double l2=z3/(z3-z2);
|
||||
l2=fix(x2, y2, z2, x3, y3, z3, l2);
|
||||
final double m2=1-l2;
|
||||
v.add(new Coordinates(l1*x1+m1*x2, l1*y1+m1*y2, l2*x2+m2*x3, l2*y2+m2*y3));
|
||||
}
|
||||
} else if (z1*z3<0) {
|
||||
double l1=z3/(z3-z1);
|
||||
l1=fix(x1, y1, z1, x3, y3, z3, l1);
|
||||
final double m1=1-l1;
|
||||
double l2=z3/(z3-z2);
|
||||
l2=fix(x2, y2, z2, x3, y3, z3, l2);
|
||||
final double m2=1-l2;
|
||||
v.add(new Coordinates(l1*x1+m1*x3, l1*y1+m1*y3, l2*x2+m2*x3, l2*y2+m2*y3));
|
||||
}
|
||||
}
|
||||
double xv[]=new double[2];
|
||||
|
||||
public double fix(final double x1, final double y1, final double z1,
|
||||
final double x2, final double y2, final double z2, double l1) {
|
||||
try {
|
||||
final double z=evaluateF(x1*l1+x2*(1-l1), y1*l1+y2*(1-l1));
|
||||
if (Math.abs(z)>(Math.abs(z1)+Math.abs(z2))*1e-5) {
|
||||
final double mu=1-l1, mu2=mu*mu, mu3=mu2*mu, mu4=mu3*mu;
|
||||
final double h=Math.sqrt(mu4*z2*z2+((-2*mu4+4*mu3-2*mu2)*z1-2*mu2*z)*z2+(mu4-4*mu3+6*mu2-4*mu+1)*z1*z1+(-2*mu2+4*mu-2)*z*z1+z*z);
|
||||
final double h1=(mu2*z2-mu2*z1+z1-z+h)/(2*(mu*z2-mu*z1+z1-z));
|
||||
final double h2=(mu2*z2-mu2*z1+z1-z-h)/(2*(mu*z2-mu*z1+z1-z));
|
||||
if (h1>=0&&h1<=1) {
|
||||
l1=1-h1;
|
||||
} else if (h2>=0&&h2<=1) {
|
||||
l1=1-h2;
|
||||
}
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
return l1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(final MyGraphics g, final ZirkelCanvas zc) {
|
||||
if (!Valid||mustHide(zc)) {
|
||||
return;
|
||||
}
|
||||
Coordinates c1;
|
||||
g.setColor(this);
|
||||
final Enumeration e=V.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
c1=(Coordinates) e.nextElement();
|
||||
g.drawLine(zc.col(c1.X), zc.row(c1.Y), zc.col(c1.X1),
|
||||
zc.row(c1.Y1), this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int cc, final int rr, final ZirkelCanvas zc) {
|
||||
|
||||
final Enumeration e=V.elements();
|
||||
Coordinates c1;
|
||||
while (e.hasMoreElements()) {
|
||||
c1=(Coordinates) e.nextElement();
|
||||
if (((Math.abs(zc.col(c1.X)-cc)+Math.abs(zc.row(c1.Y)-rr))<5)||((Math.abs(zc.col(c1.X1)-cc)+Math.abs(zc.row(c1.Y1)-rr))<5)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getDistance(final PointObject P) {
|
||||
xx=P.getX();
|
||||
yy=P.getY();
|
||||
Coordinates c;
|
||||
double dd, dm=0, xm1=0, ym1=0, zm1=0, xm2=0, ym2=0, zm2=0;
|
||||
|
||||
// search the closer segment [M1M2] :
|
||||
final Enumeration e=V.elements();
|
||||
if (e.hasMoreElements()) {
|
||||
c=(Coordinates) e.nextElement();
|
||||
xm1=c.X;
|
||||
ym1=c.Y;
|
||||
xm2=c.X1;
|
||||
ym2=c.Y1;
|
||||
dm=Math.sqrt((c.X-xx)*(c.X-xx)+(c.Y-yy)*(c.Y-yy))+Math.sqrt((c.X1-xx)*(c.X1-xx)+(c.Y1-yy)*(c.Y1-yy))-Math.sqrt((c.X-c.X1)*(c.X-c.X1)+(c.Y-c.Y1)*(c.Y-c.Y1));
|
||||
} else {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
while (e.hasMoreElements()) {
|
||||
c=(Coordinates) e.nextElement();
|
||||
dd=Math.sqrt((c.X-xx)*(c.X-xx)+(c.Y-yy)*(c.Y-yy))+Math.sqrt((c.X1-xx)*(c.X1-xx)+(c.Y1-yy)*(c.Y1-yy))-Math.sqrt((c.X-c.X1)*(c.X-c.X1)+(c.Y-c.Y1)*(c.Y-c.Y1));
|
||||
if (dd<dm) {
|
||||
xm1=c.X;
|
||||
ym1=c.Y;
|
||||
xm2=c.X1;
|
||||
ym2=c.Y1;
|
||||
dm=dd;
|
||||
}
|
||||
}
|
||||
|
||||
// coords du vecteur unitaire directeur de (M1M2) :
|
||||
double lg=Math.sqrt((xm2-xm1)*(xm2-xm1)+(ym2-ym1)*(ym2-ym1));
|
||||
double dx=(xm2-xm1)/lg;
|
||||
double dy=(ym2-ym1)/lg;
|
||||
|
||||
// coords du point H projeté ortho de P sur (M1M2) :
|
||||
final double h=(xx-xm1)*dx+(yy-ym1)*dy;
|
||||
final double xh=xm1+h*dx;
|
||||
final double yh=ym1+h*dy;
|
||||
|
||||
// coords du vecteur unitaire directeur de (HP) :
|
||||
lg=Math.sqrt((xx-xh)*(xx-xh)+(yy-yh)*(yy-yh));
|
||||
dx=(xx-xh)/lg;
|
||||
dy=(yy-yh)/lg;
|
||||
|
||||
// ten pixel length :
|
||||
final double d10=10/C.getPixel();
|
||||
|
||||
// Try to have a very accurate precision :
|
||||
try {
|
||||
xm1=xh+d10*dx;
|
||||
ym1=yh+d10*dy;
|
||||
zm1=evaluateF(xm1, ym1);
|
||||
xm2=xh-d10*dx;
|
||||
ym2=yh-d10*dy;
|
||||
zm2=evaluateF(xm2, ym2);
|
||||
if (zm1*zm2<0) {
|
||||
findRootBetween(xm1, ym1, zm1, xm2, ym2, zm2);
|
||||
dd=Math.sqrt((P.getX()-xx)*(P.getX()-xx)+(P.getY()-yy)*(P.getY()-yy));
|
||||
return (int) Math.round(dd*Cn.getPixel());
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
}
|
||||
|
||||
// If nothing found, then sorry... :
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
public void project(final PointObject P) {
|
||||
|
||||
xx=P.getX();
|
||||
yy=P.getY();
|
||||
Coordinates c;
|
||||
double dd, dm=0, xm1=0, ym1=0, zm1=0, xm2=0, ym2=0, zm2=0;
|
||||
|
||||
// search the closer segment [M1M2] :
|
||||
final Enumeration e=V.elements();
|
||||
if (e.hasMoreElements()) {
|
||||
c=(Coordinates) e.nextElement();
|
||||
xm1=c.X;
|
||||
ym1=c.Y;
|
||||
xm2=c.X1;
|
||||
ym2=c.Y1;
|
||||
dm=Math.sqrt((c.X-xx)*(c.X-xx)+(c.Y-yy)*(c.Y-yy))+Math.sqrt((c.X1-xx)*(c.X1-xx)+(c.Y1-yy)*(c.Y1-yy))-Math.sqrt((c.X-c.X1)*(c.X-c.X1)+(c.Y-c.Y1)*(c.Y-c.Y1));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
while (e.hasMoreElements()) {
|
||||
c=(Coordinates) e.nextElement();
|
||||
dd=Math.sqrt((c.X-xx)*(c.X-xx)+(c.Y-yy)*(c.Y-yy))+Math.sqrt((c.X1-xx)*(c.X1-xx)+(c.Y1-yy)*(c.Y1-yy))-Math.sqrt((c.X-c.X1)*(c.X-c.X1)+(c.Y-c.Y1)*(c.Y-c.Y1));
|
||||
if (dd<dm) {
|
||||
xm1=c.X;
|
||||
ym1=c.Y;
|
||||
xm2=c.X1;
|
||||
ym2=c.Y1;
|
||||
dm=dd;
|
||||
}
|
||||
}
|
||||
|
||||
// coords du vecteur unitaire directeur de (M1M2) :
|
||||
double lg=Math.sqrt((xm2-xm1)*(xm2-xm1)+(ym2-ym1)*(ym2-ym1));
|
||||
double dx=(xm2-xm1)/lg;
|
||||
double dy=(ym2-ym1)/lg;
|
||||
|
||||
// coords du point H projeté ortho de P sur (M1M2) :
|
||||
final double h=(xx-xm1)*dx+(yy-ym1)*dy;
|
||||
final double xh=xm1+h*dx;
|
||||
final double yh=ym1+h*dy;
|
||||
|
||||
// coords du vecteur unitaire directeur de (HP) :
|
||||
lg=Math.sqrt((xx-xh)*(xx-xh)+(yy-yh)*(yy-yh));
|
||||
dx=(xx-xh)/lg;
|
||||
dy=(yy-yh)/lg;
|
||||
|
||||
// ten pixel length :
|
||||
final double d10=10/C.getPixel();
|
||||
|
||||
// Try to have a very accurate precision :
|
||||
try {
|
||||
xm1=xh+d10*dx;
|
||||
ym1=yh+d10*dy;
|
||||
zm1=evaluateF(xm1, ym1);
|
||||
xm2=xh-d10*dx;
|
||||
ym2=yh-d10*dy;
|
||||
zm2=evaluateF(xm2, ym2);
|
||||
if (zm1*zm2<0) {
|
||||
findRootBetween(xm1, ym1, zm1, xm2, ym2, zm2);
|
||||
P.move(xx, yy);
|
||||
return;
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
}
|
||||
|
||||
// If nothing found, then project on the segment (low precision) :
|
||||
P.move(xh, yh);
|
||||
}
|
||||
double xx, yy, zz;
|
||||
|
||||
public void findRootBetween(final double x1, final double y1,
|
||||
final double z1, final double x2, final double y2, final double z2) {
|
||||
try {
|
||||
xx=(x1+x2)/2;
|
||||
yy=(y1+y2)/2;
|
||||
zz=evaluateF(xx, yy);
|
||||
if (Math.abs(zz)<1e-10) {
|
||||
return;
|
||||
}
|
||||
if (zz*z1<0) {
|
||||
findRootBetween(x1, y1, z1, xx, yy, zz);
|
||||
} else {
|
||||
findRootBetween(xx, yy, zz, x2, y2, z2);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void project(final PointObject P, final double alpha) {
|
||||
project(P);
|
||||
}
|
||||
|
||||
public boolean canInteresectWith(final ConstructionObject o) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEY() {
|
||||
if (EY!=null) {
|
||||
return EY.toString();
|
||||
} else {
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayValue() {
|
||||
return EY.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "EqXY";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
xml.printArg("f", EY.toString());
|
||||
xml.printArg("Dhor", String.valueOf(Dhor));
|
||||
super.printArgs(xml);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
setText(getDisplayValue()+"=0");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void repulse(final PointObject P) {
|
||||
project(P);
|
||||
}
|
||||
}
|
||||
28
rene/zirkel/objects/Evaluator.java
Normal file
28
rene/zirkel/objects/Evaluator.java
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
|
||||
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;
|
||||
|
||||
import rene.zirkel.construction.ConstructionException;
|
||||
|
||||
public interface Evaluator {
|
||||
public double evaluateF(double x) throws ConstructionException;
|
||||
}
|
||||
747
rene/zirkel/objects/ExpressionObject.java
Normal file
747
rene/zirkel/objects/ExpressionObject.java
Normal file
|
|
@ -0,0 +1,747 @@
|
|||
/*
|
||||
|
||||
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: PointObject.java
|
||||
import eric.JZirkelCanvas;
|
||||
import java.awt.Color;
|
||||
import java.awt.FontMetrics;
|
||||
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.ConstructionException;
|
||||
import rene.zirkel.construction.Count;
|
||||
import rene.zirkel.expression.Expression;
|
||||
import rene.zirkel.expression.ExpressionColor;
|
||||
import rene.zirkel.expression.InvalidException;
|
||||
import rene.zirkel.graphics.MyGraphics;
|
||||
import rene.zirkel.graphics.MainGraphics;
|
||||
|
||||
public class ExpressionObject extends ConstructionObject implements
|
||||
MoveableObject, SimulationObject, DriverObject {
|
||||
|
||||
protected double X, Y;
|
||||
private static Count N=new Count();
|
||||
public Expression E;
|
||||
protected Expression EX, EY;
|
||||
protected boolean Fixed;
|
||||
String Prompt=Global.name("expression.value");
|
||||
protected double CurrentValue=0;
|
||||
protected boolean CurrentValueValid=true;
|
||||
protected boolean Slider=false;
|
||||
protected Expression SMin, SMax;
|
||||
private String LASTE="";
|
||||
private boolean isOwned=false; // tell if this expression belongs to a control
|
||||
|
||||
public ExpressionObject(final Construction c, final double x, final double y) {
|
||||
super(c);
|
||||
X=x;
|
||||
Y=y;
|
||||
setColor(ColorIndex, SpecialColor);
|
||||
updateText();
|
||||
setFixed("0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaults() {
|
||||
|
||||
setShowName(Global.getParameter("options.text.shownames", false));
|
||||
setShowValue(true);
|
||||
// setShowValue(Global.getParameter("options.text.showvalues",false));
|
||||
setColor(Global.getParameter("options.text.color", 0), Global.getParameter("options.text.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.text.colortype", 0));
|
||||
setHidden(Cn.Hidden);
|
||||
setObtuse(Cn.Obtuse);
|
||||
setSolid(Cn.Solid);
|
||||
setLarge(Cn.LargeFont);
|
||||
setBold(Cn.BoldFont);
|
||||
setPartial(Cn.Partial);
|
||||
setPrompt(this.getName()); // Dibs
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetDefaults() {
|
||||
|
||||
setShowName(Global.getParameter("options.text.shownames", false));
|
||||
setShowValue(Global.getParameter("options.text.showvalues", false));
|
||||
setColor(Global.getParameter("options.text.color", 0), Global.getParameter("options.text.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.text.colortype", 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Expression";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getN() {
|
||||
return N.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
if (E!=null) {
|
||||
setText(text3(Global.name("text.expression"), E.toString(), ""
|
||||
+roundDisplay(X), ""+roundDisplay(Y)));
|
||||
} else {
|
||||
setText(text3(Global.name("text.expression"), "", ""
|
||||
+roundDisplay(X), ""+roundDisplay(Y)));
|
||||
}
|
||||
}
|
||||
public double C, R, W, H; // for the expression position
|
||||
public double SC, SR, SW, SH; // for the slider position in screen coord.
|
||||
public double SX, SY, SD; // for the slider scale in x,y-coordinates
|
||||
|
||||
/**
|
||||
* Paint the expression. Use value, name (i.e. tag), or slider. Remember
|
||||
* slider position for nearto and drags.
|
||||
*/
|
||||
@Override
|
||||
public void paint(final MyGraphics g, final ZirkelCanvas zc) {
|
||||
DisplaysText=false;
|
||||
if (!Valid||mustHide(zc)) {
|
||||
return;
|
||||
}
|
||||
C=zc.col(X);
|
||||
R=zc.row(Y);
|
||||
setFont(g);
|
||||
final FontMetrics fm=g.getFontMetrics();
|
||||
if (isStrongSelected()&&g instanceof MyGraphics) {
|
||||
((MainGraphics) g).drawMarkerRect(C-5, R-5, 10, 10);
|
||||
}
|
||||
g.setColor(this);
|
||||
String s="";
|
||||
if (showName()) // shows the tag with or without = ...
|
||||
{
|
||||
s=Prompt;
|
||||
if (showValue()) // =, if value shows and % is not surpressed
|
||||
{
|
||||
if (s.endsWith("_")&&s.length()>1) {
|
||||
s=s.substring(0, s.length()-1);
|
||||
} else {
|
||||
if (!s.equals("")) {
|
||||
s=s+" = ";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s=Prompt;
|
||||
}
|
||||
}
|
||||
if (showValue()) // show the value
|
||||
{
|
||||
try {
|
||||
E.getValue();
|
||||
double x=round(CurrentValue);
|
||||
if (Slider) {
|
||||
x=round(CurrentValue, 100);
|
||||
}
|
||||
if (Math.abs(x-Math.round(x))<1e-10) {
|
||||
s=s+Global.getLocaleNumber((int) x, "edit");
|
||||
// s = s + (int) x;
|
||||
} else {
|
||||
s=s+Global.getLocaleNumber(x, "edit");
|
||||
// s = s + x;
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
s=s+"???";
|
||||
}
|
||||
}
|
||||
s=s+Unit; // add optional unit
|
||||
s=AngleObject.translateToUnicode(s); // translate \a etc.
|
||||
// s=s.replace(".",",");
|
||||
|
||||
if (s.equals("")) // nothing to show
|
||||
{
|
||||
if (!Slider) {
|
||||
s="-";
|
||||
}
|
||||
}
|
||||
W=fm.stringWidth(s);
|
||||
if (!s.equals("")) {
|
||||
setFont(g);
|
||||
R-=fm.getAscent();
|
||||
H=g.drawStringExtended(s, C, R);
|
||||
//W=((MyGraphics13) g).getW();//pb export eps et svg, il faut un double
|
||||
}
|
||||
if (Slider) // we draw an additional slider
|
||||
{
|
||||
final int coffset=(int) (4*zc.pointSize());
|
||||
R+=H;
|
||||
g.drawLine(C, R+coffset/2, C+10*coffset, R+coffset/2);
|
||||
|
||||
final double d=getSliderPosition();
|
||||
final int size=coffset/4;
|
||||
final double rslider=C+d*10*coffset;
|
||||
final double cw=2*size+2;
|
||||
|
||||
if (getColorType()==THICK) {
|
||||
g.fillOval(rslider-size-1, R+coffset/2-size-1, cw,
|
||||
cw, true, false, this);
|
||||
} else {
|
||||
g.fillOval(rslider-size-1, R+coffset/2-size-1, cw,
|
||||
cw, new Color(250, 250, 250));
|
||||
g.setColor(this);
|
||||
g.drawOval(rslider-size-1, R+coffset/2-size-1, cw,
|
||||
cw);
|
||||
}
|
||||
// remember position
|
||||
SC=rslider-size;
|
||||
SR=R+coffset/2-size;
|
||||
SW=SH=2*size;
|
||||
SX=zc.x((int) C);
|
||||
SY=zc.y((int) R+coffset/2-size);
|
||||
SD=zc.x((int) C+10*coffset)-SX;
|
||||
|
||||
R-=H;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the relative position, the slider must be on according to
|
||||
* CurrentValue
|
||||
*
|
||||
* @return 0 <= position <= 1
|
||||
*/
|
||||
public double getSliderPosition() {
|
||||
try {
|
||||
final double min=SMin.getValue();
|
||||
final double max=SMax.getValue();
|
||||
double x=CurrentValue;
|
||||
if (min>=max) {
|
||||
Valid=false;
|
||||
return 0;
|
||||
}
|
||||
if (x<min) {
|
||||
x=min;
|
||||
}
|
||||
if (x>max) {
|
||||
x=max;
|
||||
}
|
||||
return (x-min)/(max-min);
|
||||
} catch (final Exception e) {
|
||||
Valid=false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the expression according to the relative value the slider is on. 0 <=
|
||||
* d <= 1.
|
||||
*
|
||||
* @param d
|
||||
*/
|
||||
public void setSliderPosition(final double d) {
|
||||
try {
|
||||
final double min=SMin.getValue();
|
||||
final double max=SMax.getValue();
|
||||
if (min>=max) {
|
||||
Valid=false;
|
||||
return;
|
||||
}
|
||||
double value=min+d*(max-min);
|
||||
if (value<min) {
|
||||
value=min;
|
||||
}
|
||||
if (value>max) {
|
||||
value=max;
|
||||
}
|
||||
E.setValue(value); // kills expression and makes it a constant
|
||||
} catch (final Exception e) {
|
||||
Valid=false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int x, final int y, final ZirkelCanvas zc) {
|
||||
DragSlider=false;
|
||||
|
||||
if (Valid&&!displays(zc)) {
|
||||
return false;
|
||||
}
|
||||
if (C<=x&&x<=C+W&&R<=y&&y<=R+H) {
|
||||
return true;
|
||||
}
|
||||
if (SC<=x&&SR<=y&&SC+SW>=x&&SR+SH>=y) {
|
||||
DragSlider=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getX() {
|
||||
return X;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getY() {
|
||||
return Y;
|
||||
}
|
||||
|
||||
public Expression getExp() {
|
||||
return E;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(final double x, final double y) {
|
||||
X=x;
|
||||
Y=y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void snap(final ZirkelCanvas zc) {
|
||||
final double d=zc.getGridSize()/2;
|
||||
X=Math.round(X/d)*d;
|
||||
Y=Math.round(Y/d)*d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void round() {
|
||||
move(round(X, ZirkelCanvas.LengthsFactor), round(Y,
|
||||
ZirkelCanvas.LengthsFactor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
if (Fixed&&EX!=null&&EX.isValid()) {
|
||||
xml.printArg("x", EX.toString());
|
||||
} else {
|
||||
xml.printArg("x", ""+X);
|
||||
}
|
||||
if (Fixed&&EY!=null&&EY.isValid()) {
|
||||
xml.printArg("y", EY.toString());
|
||||
} else {
|
||||
xml.printArg("y", ""+Y);
|
||||
}
|
||||
if (E!=null) {
|
||||
xml.printArg("value", E.toString());
|
||||
} else {
|
||||
xml.printArg("value", "");
|
||||
}
|
||||
xml.printArg("prompt", Prompt);
|
||||
if (Fixed) {
|
||||
xml.printArg("fixed", "true");
|
||||
}
|
||||
if (Slider) {
|
||||
xml.printArg("slider", "true");
|
||||
xml.printArg("min", SMin.toString());
|
||||
xml.printArg("max", SMax.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final ConstructionObject o) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpression(final String expr, final Construction c)
|
||||
throws ConstructionException {
|
||||
E=new Expression(expr, c, this);
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFixed(final String expr) {
|
||||
E=new Expression(expr, getConstruction(), this);
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression() {
|
||||
if (E!=null) {
|
||||
return E.toString();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// public Enumeration depending() {
|
||||
// DL.reset();
|
||||
// if (E != null) {
|
||||
// Enumeration e = E.getDepList().elements();
|
||||
// while (e.hasMoreElements()) {
|
||||
// DL.add((ConstructionObject) e.nextElement());
|
||||
// }
|
||||
// }
|
||||
// if (Fixed) {
|
||||
// Enumeration e;
|
||||
// if (EX != null) {
|
||||
// e = EX.getDepList().elements();
|
||||
// while (e.hasMoreElements()) {
|
||||
// DL.add((ConstructionObject) e.nextElement());
|
||||
// }
|
||||
// }
|
||||
// if (EY != null) {
|
||||
// e = EY.getDepList().elements();
|
||||
// while (e.hasMoreElements()) {
|
||||
// DL.add((ConstructionObject) e.nextElement());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return DL.elements();
|
||||
// }
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
DL.reset();
|
||||
addDepending(E);
|
||||
addDepending(SMin);
|
||||
addDepending(SMax);
|
||||
if (Fixed) {
|
||||
addDepending(EX);
|
||||
addDepending(EY);
|
||||
}
|
||||
return DL.elements();
|
||||
}
|
||||
|
||||
public void addDepending(final Expression EE) {
|
||||
if (EE!=null) {
|
||||
final Enumeration e=EE.getDepList().elements();
|
||||
while (e.hasMoreElements()) {
|
||||
DL.add((ConstructionObject) e.nextElement());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue() throws ConstructionException {
|
||||
if (!CurrentValueValid) {
|
||||
throw new InvalidException("");
|
||||
}
|
||||
return CurrentValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrompt() {
|
||||
return Prompt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrompt(final String prompt) {
|
||||
Prompt=prompt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
|
||||
if (Slider) {
|
||||
SMin.translate();
|
||||
SMax.translate();
|
||||
} else {
|
||||
E.translate();
|
||||
}
|
||||
|
||||
if (Fixed) {
|
||||
try {
|
||||
setFixed(EX.toString(), EY.toString());
|
||||
EX.translate();
|
||||
EY.translate();
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
}
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
double oldV;
|
||||
|
||||
try {
|
||||
oldV=CurrentValue;
|
||||
CurrentValue=E.getValue();
|
||||
CurrentValueValid=true;
|
||||
if (oldV!=CurrentValue) {
|
||||
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
CurrentValueValid=false;
|
||||
}
|
||||
Valid=true;
|
||||
if (Fixed&&EX!=null&&EX.isValid()) {
|
||||
try {
|
||||
X=EX.getValue();
|
||||
} catch (final Exception e) {
|
||||
Valid=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (Fixed&&EY!=null&&EY.isValid()) {
|
||||
try {
|
||||
Y=EY.getValue();
|
||||
} catch (final Exception e) {
|
||||
Valid=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFixed(final boolean flag) {
|
||||
Fixed=flag;
|
||||
if (!Fixed) {
|
||||
EX=EY=null;
|
||||
}
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFixed(final String x, final String y) {
|
||||
Fixed=true;
|
||||
EX=new Expression(x, getConstruction(), this);
|
||||
EY=new Expression(y, getConstruction(), this);
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructionObject copy(final double x, final double y) {
|
||||
try {
|
||||
final ExpressionObject o=(ExpressionObject) clone();
|
||||
setTranslation(o);
|
||||
|
||||
if (Slider) {
|
||||
o.setSlider(SMin.toString(), SMax.toString());
|
||||
} else {
|
||||
o.setExpression(E.toString(), getConstruction());
|
||||
}
|
||||
|
||||
o.translateConditionals();
|
||||
o.translate();
|
||||
o.setName();
|
||||
o.updateText();
|
||||
o.setBreak(false);
|
||||
// o.setTarget(false);
|
||||
return o;
|
||||
} catch (final Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean moveable() {
|
||||
if (Slider) {
|
||||
return true;
|
||||
}
|
||||
return EX==null&&EY==null;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
if (E!=null) {
|
||||
E.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fixed() {
|
||||
return Fixed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEX() {
|
||||
if (EX!=null) {
|
||||
return EX.toString();
|
||||
} else {
|
||||
return ""+round(X);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEY() {
|
||||
if (EY!=null) {
|
||||
return EY.toString();
|
||||
} else {
|
||||
return ""+round(Y);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCurrentValue(final double x) {
|
||||
CurrentValue=x;
|
||||
CurrentValueValid=true;
|
||||
}
|
||||
// For the simulate function:
|
||||
private double OldE;
|
||||
|
||||
/**
|
||||
* Set the simulation value, remember the old value.
|
||||
*/
|
||||
public void setSimulationValue(final double x) {
|
||||
OldE=CurrentValue;
|
||||
CurrentValue=x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the old value.
|
||||
*/
|
||||
public void resetSimulationValue() {
|
||||
CurrentValue=OldE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the slider to min, max und step values.
|
||||
*
|
||||
* @param smin
|
||||
* @param smax
|
||||
* @param sstep
|
||||
*/
|
||||
@Override
|
||||
public void setSlider(final String smin, final String smax) {
|
||||
Slider=true;
|
||||
SMin=new Expression(smin, getConstruction(), this);
|
||||
SMax=new Expression(smax, getConstruction(), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or clear the slider.
|
||||
*
|
||||
* @param flag
|
||||
*/
|
||||
@Override
|
||||
public void setSlider(final boolean flag) {
|
||||
Slider=flag;
|
||||
}
|
||||
double oldx, oldy, startx, starty;
|
||||
boolean DragSlider;
|
||||
|
||||
public void startDrag(final double x, final double y) {
|
||||
oldx=X;
|
||||
oldy=Y;
|
||||
startx=x;
|
||||
starty=y;
|
||||
}
|
||||
|
||||
public void dragTo(final double x, final double y) {
|
||||
if (DragSlider) {
|
||||
setSliderPosition((x-SX)/SD);
|
||||
} else {
|
||||
move(oldx+(x-startx), oldy+(y-starty));
|
||||
}
|
||||
}
|
||||
|
||||
public double getOldX() {
|
||||
return oldx;
|
||||
}
|
||||
|
||||
public double getOldY() {
|
||||
return oldy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSlider() {
|
||||
return Slider;
|
||||
}
|
||||
|
||||
public double getMinValue() {
|
||||
try {
|
||||
double d=SMin.getValue();
|
||||
return d;
|
||||
} catch (Exception ex) {
|
||||
return -5;
|
||||
}
|
||||
}
|
||||
|
||||
public double getMaxValue() {
|
||||
try {
|
||||
double d=SMax.getValue();
|
||||
return d;
|
||||
} catch (Exception ex) {
|
||||
return -5;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMin() {
|
||||
if (Slider) {
|
||||
return SMin.toString();
|
||||
} else {
|
||||
return ("-5");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMax() {
|
||||
if (Slider) {
|
||||
return SMax.toString();
|
||||
} else {
|
||||
return ("5");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayValue() {
|
||||
|
||||
String s="";
|
||||
try {
|
||||
E.getValue();
|
||||
double x=round(CurrentValue);
|
||||
if (Slider) {
|
||||
x=round(CurrentValue, 100);
|
||||
}
|
||||
if (Math.abs(x-Math.round(x))<1e-10) {
|
||||
|
||||
s=s+(int) x;
|
||||
} else {
|
||||
s=s+x;
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
s=s+"???";
|
||||
}
|
||||
s=s+Unit; // add optional unit
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEquation() {
|
||||
if (E==null) {
|
||||
return "???";
|
||||
} else {
|
||||
return E.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDriverObject() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean somethingChanged() {
|
||||
return (!getEquation().equals(LASTE));
|
||||
}
|
||||
|
||||
public void clearChanges() {
|
||||
LASTE=getEquation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOwnedByControl() {
|
||||
return isOwned;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOwnedByControl(boolean b) {
|
||||
isOwned=b;
|
||||
}
|
||||
}
|
||||
764
rene/zirkel/objects/FixedAngleObject.java
Normal file
764
rene/zirkel/objects/FixedAngleObject.java
Normal file
|
|
@ -0,0 +1,764 @@
|
|||
/*
|
||||
|
||||
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;
|
||||
|
||||
import eric.bar.JPropertiesBar;
|
||||
import java.awt.Button;
|
||||
import java.awt.Checkbox;
|
||||
import java.awt.Color;
|
||||
import java.awt.Frame;
|
||||
import java.awt.TextField;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import eric.JEricPanel;
|
||||
|
||||
import rene.dialogs.Warning;
|
||||
import rene.gui.ButtonAction;
|
||||
import rene.gui.Global;
|
||||
import rene.gui.IconBar;
|
||||
import rene.gui.MyLabel;
|
||||
import rene.gui.TextFieldAction;
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.gui.Global;
|
||||
import rene.zirkel.ZirkelCanvas;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.construction.ConstructionException;
|
||||
import rene.zirkel.construction.Count;
|
||||
import rene.zirkel.expression.Expression;
|
||||
import rene.zirkel.expression.ExpressionColor;
|
||||
import rene.zirkel.expression.InvalidException;
|
||||
import rene.zirkel.graphics.MyGraphics;
|
||||
import rene.zirkel.graphics.MainGraphics;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public class FixedAngleObject extends PrimitiveLineObject implements
|
||||
MoveableObject, SimulationObject, InsideObject {
|
||||
|
||||
protected PointObject P2;
|
||||
static Count N = new Count();
|
||||
double A, A1, A2, AA;
|
||||
Expression E;
|
||||
boolean Filled = false;
|
||||
boolean Inverse = false;
|
||||
boolean EditAborted = false;
|
||||
boolean Dragable = false;
|
||||
boolean Reduced = false;
|
||||
public static final int NORMALSIZE = 1, SMALL = 0, LARGER = 2, LARGE = 3,
|
||||
RECT = 4;
|
||||
protected int DisplaySize = NORMALSIZE;
|
||||
|
||||
public FixedAngleObject(final Construction c, final PointObject p1,
|
||||
final PointObject p2, final double x, final double y) {
|
||||
super(c);
|
||||
P1 = p1;
|
||||
P2 = p2;
|
||||
init(c, x, y);
|
||||
Unit = Global.getParameter("unit.angle", "°");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaults() {
|
||||
setShowName(Global.getParameter("options.angle.shownames", false));
|
||||
setShowValue(Global.getParameter("options.angle.showvalues", false));
|
||||
setColor(Global.getParameter("options.angle.color", 0), Global
|
||||
.getParameter("options.angle.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.angle.colortype", 0));
|
||||
setFilled(Global.getParameter("options.angle.filled", false));
|
||||
setHidden(Cn.Hidden);
|
||||
setObtuse(Global.getParameter("options.angle.obtuse", false));
|
||||
setSolid(Cn.Solid);
|
||||
setLarge(Cn.LargeFont);
|
||||
setBold(Cn.BoldFont);
|
||||
setPartial(Cn.Partial);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetDefaults() {
|
||||
setShowName(Global.getParameter("options.angle.shownames", false));
|
||||
setShowValue(Global.getParameter("options.angle.showvalues", false));
|
||||
setColor(Global.getParameter("options.angle.color", 0), Global
|
||||
.getParameter("options.angle.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.angle.colortype", 0));
|
||||
setFilled(Global.getParameter("options.angle.filled", false));
|
||||
setObtuse(Global.getParameter("options.angle.obtuse", false));
|
||||
}
|
||||
|
||||
public void init(final Construction c, final double x, final double y,
|
||||
final boolean invert) {
|
||||
double dx = P1.getX() - P2.getX(), dy = P1.getY() - P2.getY();
|
||||
A1 = Math.atan2(dy, dx);
|
||||
dx = x - P2.getX();
|
||||
dy = y - P2.getY();
|
||||
A2 = Math.atan2(dy, dx);
|
||||
A = A2 - A1;
|
||||
if (A < 0) {
|
||||
A += 2 * Math.PI;
|
||||
} else if (A > 2 * Math.PI) {
|
||||
A -= 2 * Math.PI;
|
||||
}
|
||||
if (Inverse && Obtuse) {
|
||||
A = 2 * Math.PI - A;
|
||||
}
|
||||
if (invert && !Obtuse) {
|
||||
if (A > Math.PI) {
|
||||
A = 2 * Math.PI - A;
|
||||
Inverse = true;
|
||||
} else {
|
||||
Inverse = false;
|
||||
}
|
||||
}
|
||||
E = new Expression(""
|
||||
+ round(A / Math.PI * 180, ZirkelCanvas.EditFactor), c, this);
|
||||
validate();
|
||||
setColor(ColorIndex, SpecialColor);
|
||||
updateText();
|
||||
}
|
||||
|
||||
public void init(final Construction c, final double x, final double y) {
|
||||
init(c, x, y, true);
|
||||
}
|
||||
|
||||
double xx[] = new double[4], yy[] = new double[4];
|
||||
|
||||
@Override
|
||||
public void paint(final MyGraphics g, final ZirkelCanvas zc) {
|
||||
if (!Valid || mustHide(zc)) {
|
||||
return;
|
||||
}
|
||||
// compute middle of the screen:
|
||||
final double xm = (zc.minX() + zc.maxX()) / 2, ym = (zc.minY() + zc
|
||||
.maxY()) / 2;
|
||||
// compute distance from middle to line:
|
||||
final double d = (xm - X1) * DY - (ym - Y1) * DX;
|
||||
// compute point with minimal distance
|
||||
final double x = xm - d * DY, y = ym + d * DX;
|
||||
// compute size of the screen
|
||||
final double a = Math.max(zc.maxX() - zc.minX(), zc.maxY() - zc.minY());
|
||||
if (Math.abs(d) > a) {
|
||||
return;
|
||||
}
|
||||
// compute distance from closest point to source
|
||||
final double b = (x - X1) * DX + (y - Y1) * DY;
|
||||
// compute the two visible endpoints
|
||||
double k1 = b - a;
|
||||
final double k2 = b + a;
|
||||
if (k1 < 0) {
|
||||
k1 = 0;
|
||||
}
|
||||
if (k1 >= k2) {
|
||||
return;
|
||||
}
|
||||
double c1 = zc.col(X1 + k1 * DX);
|
||||
final double c2 = zc.col(X1 + k2 * DX);
|
||||
double r1 = zc.row(Y1 + k1 * DY);
|
||||
final double r2 = zc.row(Y1 + k2 * DY);
|
||||
// paint:
|
||||
g.setColor(this);
|
||||
if (!Reduced) {
|
||||
g.drawLine(c1, r1, c2, r2, this);
|
||||
}
|
||||
final double R = zc.col(getDisplaySize(zc)) - zc.col(0);
|
||||
c1 = zc.col(X1) - R;
|
||||
r1 = zc.row(Y1) - R;
|
||||
final String s = AngleObject.translateToUnicode(getDisplayText());
|
||||
double DA = (A / Math.PI * 180);
|
||||
if (DA < 0) {
|
||||
DA += 360;
|
||||
} else if (DA >= 360) {
|
||||
DA -= 360;
|
||||
}
|
||||
if (isStrongSelected() && g instanceof MainGraphics) {
|
||||
((MainGraphics) g).drawMarkerArc(c1 + R, r1 + R, R, A1 / Math.PI
|
||||
* 180, DA);
|
||||
}
|
||||
g.setColor(this);
|
||||
if (Filled) {
|
||||
if (Math.abs(DA - 90) < 0.0000001) {
|
||||
|
||||
final double dx1 = Math.cos(A1), dy1 = Math.sin(A1), dx2 = Math
|
||||
.cos(A1 + DA / 180 * Math.PI), dy2 = Math.sin(A1 + DA
|
||||
/ 180 * Math.PI);
|
||||
final double dx3 = dx1 + dx2, dy3 = dy1 + dy2;
|
||||
xx[0] = c1;
|
||||
yy[0] = r1;
|
||||
xx[0] = c1 + R;
|
||||
yy[0] = r1 + R;
|
||||
xx[1] = c1 + R + R * dx1;
|
||||
yy[1] = r1 + R - R * dy1;
|
||||
xx[2] = c1 + R + R * dx3;
|
||||
yy[2] = r1 + R - R * dy3;
|
||||
xx[3] = c1 + R + R * dx2;
|
||||
yy[3] = r1 + R - R * dy2;
|
||||
g.fillPolygon(xx, yy, 4, false, getColorType() != THICK, this);
|
||||
g.setColor(this);
|
||||
g.drawLine(xx[1], yy[1], xx[2], yy[2]);
|
||||
g.drawLine(xx[2], yy[2], xx[3], yy[3]);
|
||||
} else {
|
||||
g.fillArc(c1, r1, 2 * R + 1, 2 * R + 1, A1 / Math.PI * 180, DA,
|
||||
Selected || getColorType() == NORMAL,
|
||||
getColorType() != THICK, true, this);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (DisplaySize == RECT) {
|
||||
final double dx1 = Math.cos(A1), dy1 = Math.sin(A1), dx2 = Math
|
||||
.cos(A1 + DA / 180 * Math.PI), dy2 = Math.sin(A1 + DA
|
||||
/ 180 * Math.PI);
|
||||
g.drawLine(c1 + R + R * dx1, r1 + R - R * dy1, c1 + R + R
|
||||
* (dx1 + dx2), r1 + R - R * (dy1 + dy2));
|
||||
g.drawLine(c1 + R + R * (dx1 + dx2), r1 + R - R * (dy1 + dy2),
|
||||
c1 + R + R * dx2, r1 + R - R * dy2);
|
||||
} else {
|
||||
|
||||
if (Math.abs(DA - 90) < 0.0000001) {
|
||||
final double dx1 = Math.cos(A1), dy1 = Math.sin(A1), dx2 = Math
|
||||
.cos(A1 + DA / 180 * Math.PI), dy2 = Math.sin(A1
|
||||
+ DA / 180 * Math.PI);
|
||||
final double dx3 = dx1 + dx2, dy3 = dy1 + dy2;
|
||||
xx[1] = c1 + R + R * dx1;
|
||||
yy[1] = r1 + R - R * dy1;
|
||||
xx[2] = c1 + R + R * dx3;
|
||||
yy[2] = r1 + R - R * dy3;
|
||||
xx[3] = c1 + R + R * dx2;
|
||||
yy[3] = r1 + R - R * dy2;
|
||||
g.setColor(this);
|
||||
g.drawLine(xx[1], yy[1], xx[2], yy[2]);
|
||||
g.drawLine(xx[2], yy[2], xx[3], yy[3]);
|
||||
} else {
|
||||
g.drawCircleArc(c1 + R, r1 + R, R, A1 / Math.PI * 180, DA,
|
||||
this);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (!s.equals("")) {
|
||||
g.setLabelColor(this);
|
||||
setFont(g);
|
||||
DisplaysText = true;
|
||||
final double dx = Math.cos(A1 + A / 2), dy = Math.sin(A1 + A / 2);
|
||||
// if (s.equals("90"+getUnit())||Name.startsWith(".")) {
|
||||
// if (KeepClose) {
|
||||
// double dof=Math.sqrt(XcOffset*XcOffset+YcOffset*YcOffset);
|
||||
// TX1=zc.col(X1+dof*dx)-3;
|
||||
// TY1=zc.row(Y1+dof*dy)-3;
|
||||
// TX2=TX1+9;
|
||||
// TY2=TY1+9;
|
||||
// g.drawRect(zc.col(X1+dof*dx)-1,
|
||||
// zc.row(Y1+dof*dy)-1, 3, 3);
|
||||
// } else {
|
||||
// TX1=zc.col(X1+zc.dx(R*AngleObject.LabelScale)*dx+XcOffset)-3;
|
||||
// TY1=zc.row(Y1+zc.dy(R*AngleObject.LabelScale)*dy+YcOffset)-3;
|
||||
// TX2=TX1+9;
|
||||
// TY2=TY1+9;
|
||||
// g.drawRect(zc.col(X1+zc.dx(R*AngleObject.LabelScale)*dx+XcOffset)-1,
|
||||
// zc.row(Y1+zc.dy(R*AngleObject.LabelScale)*dy+YcOffset)-1, 3, 3);
|
||||
// }
|
||||
// } else {
|
||||
if (KeepClose) {
|
||||
final double dof = Math.sqrt(XcOffset * XcOffset + YcOffset
|
||||
* YcOffset);
|
||||
drawCenteredLabel(g, s, zc, X1 + dof * dx, Y1 + dof * dy, 0, 0);
|
||||
} else {
|
||||
drawCenteredLabel(g, s, zc, X1
|
||||
+ zc.dx(R * AngleObject.LabelScale) * dx, Y1
|
||||
+ zc.dy(R * AngleObject.LabelScale) * dy, XcOffset,
|
||||
YcOffset);
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canKeepClose() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setKeepClose(final double x, final double y) {
|
||||
KeepClose = true;
|
||||
XcOffset = x - X1;
|
||||
YcOffset = y - Y1;
|
||||
}
|
||||
|
||||
double getDisplaySize(final ZirkelCanvas zc) {
|
||||
double R = zc.dx(12 * zc.pointSize());
|
||||
if (DisplaySize == SMALL || DisplaySize == RECT) {
|
||||
R /= 2;
|
||||
} else if (DisplaySize == LARGER) {
|
||||
R *= 2;
|
||||
} else if (DisplaySize == LARGE) {
|
||||
final double dx = P1.getX() - X1, dy = P1.getY() - Y1;
|
||||
R = Math.sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
return R;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Angle";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getN() {
|
||||
return N.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
if (E == null || !E.isValid()) {
|
||||
return;
|
||||
}
|
||||
setText(text3(Global.name("text.fixedangle"), P1.getName(), P2
|
||||
.getName(), E.toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayValue() {
|
||||
return Global.getLocaleNumber(A / Math.PI * 180, "angles");
|
||||
}
|
||||
|
||||
// public String getDisplayValue() {
|
||||
// if (ZirkelCanvas.AnglesFactor<=2) {
|
||||
// return ""+(int) (A/Math.PI*180+0.5);
|
||||
// } else {
|
||||
// return ""+round(A/Math.PI*180, ZirkelCanvas.AnglesFactor);
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
if (!P1.valid() || !P2.valid()) {
|
||||
Valid = false;
|
||||
return;
|
||||
} else {
|
||||
X1 = P2.getX();
|
||||
Y1 = P2.getY();
|
||||
final double dx = P1.getX() - X1, dy = P1.getY() - Y1;
|
||||
if (Math.sqrt(dx * dx + dy * dy) < 1e-9) {
|
||||
Valid = false;
|
||||
return;
|
||||
}
|
||||
A1 = Math.atan2(dy, dx);
|
||||
boolean Negative = false;
|
||||
try {
|
||||
if (E != null && E.isValid()) {
|
||||
A = E.getValue() / 180 * Math.PI;
|
||||
}
|
||||
if (Obtuse) {
|
||||
if (Inverse) {
|
||||
A = -A;
|
||||
}
|
||||
} else {
|
||||
if (Inverse && Math.sin(A) > 0) {
|
||||
A = -A;
|
||||
}
|
||||
if (!Inverse && Math.sin(A) < 0) {
|
||||
A = -A;
|
||||
}
|
||||
}
|
||||
if (A < 0) {
|
||||
Negative = true;
|
||||
}
|
||||
while (A < 0) {
|
||||
A = A + 2 * Math.PI;
|
||||
}
|
||||
while (A >= 2 * Math.PI) {
|
||||
A = A - 2 * Math.PI;
|
||||
}
|
||||
A2 = A1 + A;
|
||||
DX = Math.cos(A2);
|
||||
DY = Math.sin(A2);
|
||||
AA = A;
|
||||
} catch (final Exception e) {
|
||||
Valid = false;
|
||||
return;
|
||||
}
|
||||
if (!Obtuse && A > Math.PI) {
|
||||
A1 = A2;
|
||||
A = 2 * Math.PI - A;
|
||||
A2 = A1 + A;
|
||||
} else if (Obtuse && Negative) {
|
||||
A1 = A2;
|
||||
A = 2 * Math.PI - A;
|
||||
A2 = A1 + A;
|
||||
}
|
||||
Valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
public double getLength() {
|
||||
return A;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFixed(final String s) {
|
||||
E = new Expression(s, getConstruction(), this);
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void round() {
|
||||
try {
|
||||
setFixed(round(E.getValue(), ZirkelCanvas.AnglesFactor) + "");
|
||||
validate();
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void setEditFixed(final String s) {
|
||||
E = new Expression(s, getConstruction(), this);
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canFix() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
xml.printArg("first", P1.getName());
|
||||
xml.printArg("root", P2.getName());
|
||||
if (DisplaySize == SMALL) {
|
||||
xml.printArg("display", "small");
|
||||
}
|
||||
if (DisplaySize == LARGE) {
|
||||
xml.printArg("display", "large");
|
||||
}
|
||||
if (DisplaySize == LARGER) {
|
||||
xml.printArg("display", "larger");
|
||||
}
|
||||
if (DisplaySize == RECT) {
|
||||
xml.printArg("display", "rectangle");
|
||||
}
|
||||
if (Filled) {
|
||||
xml.printArg("filled", "true");
|
||||
}
|
||||
if (E.isValid()) {
|
||||
xml.printArg("fixed", E.toString());
|
||||
} else {
|
||||
xml.printArg("fixed", "" + A / Math.PI * 180);
|
||||
}
|
||||
if (!Obtuse) {
|
||||
xml.printArg("acute", "true");
|
||||
}
|
||||
if (Inverse) {
|
||||
xml.printArg("inverse", "true");
|
||||
}
|
||||
if (Reduced) {
|
||||
xml.printArg("reduced", "true");
|
||||
}
|
||||
if (Dragable) {
|
||||
xml.printArg("dragable", "true");
|
||||
}
|
||||
super.printArgs(xml);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int c, final int r, final ZirkelCanvas zc) {
|
||||
if (!Valid && P2.valid()) {
|
||||
return P2.nearto(c, r, zc);
|
||||
}
|
||||
if (!displays(zc)) {
|
||||
return false;
|
||||
}
|
||||
// compute point at c,r
|
||||
final double x = zc.x(c), y = zc.y(r);
|
||||
// compute distance from x,y
|
||||
final double d = (x - X1) * DY - (y - Y1) * DX;
|
||||
final double e = (x - X1) * DX + (y - Y1) * DY;
|
||||
// scale in screen coordinates
|
||||
Value = Math.abs(zc.col(zc.minX() + d) - zc.col(zc.minX()));
|
||||
if (!Reduced && Value < zc.selectionSize() && e > 0) {
|
||||
return true;
|
||||
}
|
||||
final double dx = zc.x(c) - X1, dy = zc.y(r) - Y1;
|
||||
final double size = zc.dx(zc.selectionSize());
|
||||
final double rd = getDisplaySize(zc);
|
||||
final double rr = Math.sqrt(dx * dx + dy * dy);
|
||||
boolean near;
|
||||
if (Filled || DisplaySize == RECT) {
|
||||
near = (rr < rd + size);
|
||||
} else {
|
||||
near = (Math.abs(rr - rd) < size);
|
||||
}
|
||||
if (!near) {
|
||||
return false;
|
||||
}
|
||||
if (rd < size) {
|
||||
return near;
|
||||
}
|
||||
double a = Math.atan2(dy, dx);
|
||||
if (a < 0) {
|
||||
a += 2 * Math.PI;
|
||||
}
|
||||
final double cc = 0.05;
|
||||
if (A1 - cc < a && A2 + cc > a) {
|
||||
return true;
|
||||
}
|
||||
a = a - 2 * Math.PI;
|
||||
if (A1 - cc < a && A2 + cc > a) {
|
||||
return true;
|
||||
}
|
||||
a = a + 4 * Math.PI;
|
||||
if (A1 - cc < a && A2 + cc > a) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplaySize(final int i) {
|
||||
DisplaySize = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDisplaySize() {
|
||||
return DisplaySize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
super.depending();
|
||||
depset(P1, P2);
|
||||
final Enumeration e = E.getDepList().elements();
|
||||
while (e.hasMoreElements()) {
|
||||
DL.add((ConstructionObject) e.nextElement());
|
||||
}
|
||||
return DL.elements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
P1 = (PointObject) P1.getTranslation();
|
||||
P2 = (PointObject) P2.getTranslation();
|
||||
try {
|
||||
setFixed(E.toString());
|
||||
E.translate();
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getE() {
|
||||
return E.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue() throws ConstructionException {
|
||||
if (!Valid) {
|
||||
throw new InvalidException("exception.invalid");
|
||||
} else {
|
||||
return A / Math.PI * 180;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilled(final boolean flag) {
|
||||
Filled = flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFilled() {
|
||||
return Filled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFilledForSelect() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(final double x, final double y) {
|
||||
final double a = (x - X1) * DX + (y - Y1) * DY;
|
||||
if (a < 1e-9) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double project(final double x, final double y) {
|
||||
final double h = super.project(x, y);
|
||||
if (h < 0) {
|
||||
return 0;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration points() {
|
||||
super.depending();
|
||||
return depset(P2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(final double x, final double y) {
|
||||
init(getConstruction(), x, y, true);
|
||||
}
|
||||
|
||||
public boolean moveable() {
|
||||
return Dragable; // E.isNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean getInverse() {
|
||||
return Inverse;
|
||||
}
|
||||
|
||||
public void setInverse(final boolean inverse) {
|
||||
Inverse = inverse;
|
||||
}
|
||||
|
||||
public boolean isEditAborted() {
|
||||
return EditAborted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDragable() {
|
||||
return Dragable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDragable(final boolean f) {
|
||||
Dragable = f;
|
||||
}
|
||||
|
||||
public boolean isReduced() {
|
||||
return Reduced;
|
||||
}
|
||||
|
||||
public void setReduced(final boolean f) {
|
||||
Reduced = f;
|
||||
}
|
||||
|
||||
public boolean fixedByNumber() {
|
||||
return (E != null && E.isNumber());
|
||||
}
|
||||
|
||||
// For the simulate function:
|
||||
/**
|
||||
* Set the simulation value, remember the old value.
|
||||
*/
|
||||
public void setSimulationValue(final double x) {
|
||||
A = x / 180 * Math.PI;
|
||||
final Expression OldE = E;
|
||||
E = null;
|
||||
validate();
|
||||
E = OldE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the old value.
|
||||
*/
|
||||
public void resetSimulationValue() {
|
||||
validate();
|
||||
}
|
||||
|
||||
public void startDrag(final double x, final double y) {
|
||||
}
|
||||
|
||||
public void dragTo(final double x, final double y) {
|
||||
move(x, y);
|
||||
}
|
||||
|
||||
public double getOldX() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double getOldY() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double containsInside(final PointObject P) {
|
||||
final double dx = P.getX() - X1, dy = P.getY() - Y1;
|
||||
double a = Math.atan2(dy, dx);
|
||||
if (a < A1) {
|
||||
a += 2 * Math.PI;
|
||||
}
|
||||
final double c = 1e-5;
|
||||
if (a > A1 && a < A1 + A) {
|
||||
return 1;
|
||||
} else if (a > A1 - c && a < A1 + A + c) {
|
||||
return 0.5;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean keepInside(final PointObject P) {
|
||||
if (containsInside(P) > 0) {
|
||||
return true;
|
||||
}
|
||||
final double x = P.getX(), y = P.getY();
|
||||
final double x1 = X1, y1 = Y1;
|
||||
double xmin = x1, ymin = y1, dmin = 1e20;
|
||||
double x2 = X1 + Math.cos(A1), y2 = Y1 + Math.sin(A1);
|
||||
double dx = x2 - x1, dy = y2 - y1;
|
||||
double r = dx * dx + dy * dy;
|
||||
double h = dx * (x - x1) / r + dy * (y - y1) / r;
|
||||
if (h < 0) {
|
||||
h = 0;
|
||||
}
|
||||
double xh = x1 + h * dx, yh = y1 + h * dy;
|
||||
double dist = Math.sqrt((x - xh) * (x - xh) + (y - yh) * (y - yh));
|
||||
if (dist < dmin) {
|
||||
dmin = dist;
|
||||
xmin = xh;
|
||||
ymin = yh;
|
||||
}
|
||||
x2 = X1 + Math.cos(A2);
|
||||
y2 = Y1 + Math.sin(A2);
|
||||
dx = x2 - x1;
|
||||
dy = y2 - y1;
|
||||
r = dx * dx + dy * dy;
|
||||
h = dx * (x - x1) / r + dy * (y - y1) / r;
|
||||
if (h < 0) {
|
||||
h = 0;
|
||||
}
|
||||
xh = x1 + h * dx;
|
||||
yh = y1 + h * dy;
|
||||
dist = Math.sqrt((x - xh) * (x - xh) + (y - yh) * (y - yh));
|
||||
if (dist < dmin) {
|
||||
dmin = dist;
|
||||
xmin = xh;
|
||||
ymin = yh;
|
||||
}
|
||||
P.move(xmin, ymin);
|
||||
return false;
|
||||
}
|
||||
public PointObject getP1() {
|
||||
return P1;
|
||||
}
|
||||
public PointObject getP2() {
|
||||
return P2;
|
||||
}
|
||||
}
|
||||
270
rene/zirkel/objects/FixedCircleObject.java
Normal file
270
rene/zirkel/objects/FixedCircleObject.java
Normal file
|
|
@ -0,0 +1,270 @@
|
|||
/*
|
||||
|
||||
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: CircleObject.java
|
||||
|
||||
import eric.bar.JPropertiesBar;
|
||||
import java.awt.Frame;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import rene.dialogs.Warning;
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.gui.Global;
|
||||
import rene.zirkel.ZirkelCanvas;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.construction.ConstructionException;
|
||||
import rene.zirkel.expression.Expression;
|
||||
import rene.zirkel.expression.InvalidException;
|
||||
|
||||
public class FixedCircleObject extends PrimitiveCircleObject implements
|
||||
MoveableObject, SimulationObject {
|
||||
Expression E;
|
||||
boolean EditAborted = false;
|
||||
boolean Dragable = false;
|
||||
|
||||
public FixedCircleObject(final Construction c, final PointObject p1,
|
||||
final double x, final double y) {
|
||||
super(c, p1);
|
||||
init(c, x, y);
|
||||
}
|
||||
|
||||
public void init(final Construction c, final double x, final double y) {
|
||||
|
||||
E = new Expression(""
|
||||
+ Math.sqrt((x - M.getX()) * (x - M.getX()) + (y - M.getY())
|
||||
* (y - M.getY())), c, this);
|
||||
validate();
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Circle";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
if (E == null || !E.isValid()) {
|
||||
return;
|
||||
}
|
||||
if (M.is3D()) setText(text2(Global.name("text.sphere"), M.getName(), ""
|
||||
+ E.toString()));
|
||||
else setText(text2(Global.name("text.fixedcircle"), M.getName(), ""
|
||||
+ E.toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
super.validate();
|
||||
if (!M.valid()) {
|
||||
Valid = false;
|
||||
return;
|
||||
}
|
||||
Valid = true;
|
||||
X = M.getX();
|
||||
Y = M.getY();
|
||||
if (E != null && !E.isValid()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (E != null) {
|
||||
R = E.getValue();
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
R = 0;
|
||||
Valid = false;
|
||||
}
|
||||
if (R < -1e-10) {
|
||||
Valid = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
if (E.isValid()) {
|
||||
xml.printArg("fixed", E.toString());
|
||||
} else {
|
||||
xml.printArg("fixed", "" + R);
|
||||
}
|
||||
if (Dragable) {
|
||||
xml.printArg("dragable", "true");
|
||||
}
|
||||
super.printArgs(xml);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canFix() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFixed(final String s) {
|
||||
E = new Expression(s, getConstruction(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void round() {
|
||||
try {
|
||||
setFixed(round(E.getValue(), ZirkelCanvas.LengthsFactor) + "");
|
||||
validate();
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int c, final int r, final ZirkelCanvas zc) {
|
||||
if (!Valid && M.valid()) {
|
||||
return M.nearto(c, r, zc);
|
||||
}
|
||||
return super.nearto(c, r, zc);
|
||||
}
|
||||
|
||||
public boolean isValidFix() {
|
||||
return E.isValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
super.translate();
|
||||
try {
|
||||
setFixed(E.toString());
|
||||
E.translate();
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStringLength() {
|
||||
return E.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue() throws ConstructionException {
|
||||
if (!Valid) {
|
||||
throw new InvalidException("exception.invalid");
|
||||
} else {
|
||||
return R;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
super.depending();
|
||||
final Enumeration e = E.getDepList().elements();
|
||||
while (e.hasMoreElements()) {
|
||||
DL.add((ConstructionObject) e.nextElement());
|
||||
}
|
||||
return DL.elements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(final double x, final double y) {
|
||||
init(getConstruction(), x, y);
|
||||
}
|
||||
|
||||
public boolean moveable() {
|
||||
return Dragable || M.moveable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFixed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isEditAborted() {
|
||||
return EditAborted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDragable() {
|
||||
return Dragable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDragable(final boolean f) {
|
||||
Dragable = f;
|
||||
}
|
||||
|
||||
public boolean fixedByNumber() {
|
||||
return (E != null && E.isNumber());
|
||||
}
|
||||
|
||||
// For the simulate function:
|
||||
/**
|
||||
* Set the simulation value, remember the old value.
|
||||
*/
|
||||
public void setSimulationValue(final double x) {
|
||||
R = x;
|
||||
final Expression OldE = E;
|
||||
E = null;
|
||||
validate();
|
||||
E = OldE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the old value.
|
||||
*/
|
||||
public void resetSimulationValue() {
|
||||
validate();
|
||||
}
|
||||
|
||||
double x1, y1, x2, y2;
|
||||
|
||||
public void startDrag(final double x, final double y) {
|
||||
x1 = M.getX();
|
||||
y1 = M.getY();
|
||||
x2 = x;
|
||||
y2 = y;
|
||||
}
|
||||
|
||||
public void dragTo(final double x, final double y) {
|
||||
if (Dragable) {
|
||||
move(x, y);
|
||||
} else {
|
||||
M.move(x1 + (x - x2), y1 + (y - y2));
|
||||
}
|
||||
}
|
||||
|
||||
public double getOldX() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double getOldY() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void snap(final ZirkelCanvas zc) {
|
||||
if (moveable() && !Dragable) {
|
||||
M.snap(zc);
|
||||
}
|
||||
}
|
||||
}
|
||||
1401
rene/zirkel/objects/FunctionObject.java
Normal file
1401
rene/zirkel/objects/FunctionObject.java
Normal file
File diff suppressed because it is too large
Load diff
33
rene/zirkel/objects/HeavyObject.java
Normal file
33
rene/zirkel/objects/HeavyObject.java
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
|
||||
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;
|
||||
|
||||
import rene.zirkel.construction.Construction;
|
||||
|
||||
public interface HeavyObject {
|
||||
public void compute();
|
||||
|
||||
public boolean needsToRecompute();
|
||||
|
||||
public void searchDependencies(Construction c);
|
||||
|
||||
}
|
||||
171
rene/zirkel/objects/ImageObject.java
Normal file
171
rene/zirkel/objects/ImageObject.java
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
|
||||
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;
|
||||
|
||||
import eric.Media;
|
||||
import java.awt.Image;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import rene.util.FileName;
|
||||
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.graphics.MyGraphics;
|
||||
|
||||
public class ImageObject extends ConstructionObject {
|
||||
|
||||
PointObject P[];
|
||||
static Count N=new Count();
|
||||
String Filename;
|
||||
Image I;
|
||||
|
||||
public ImageObject(final Construction c, final PointObject p[],
|
||||
final String filename) {
|
||||
super(c);
|
||||
P=p;
|
||||
Filename=FileName.filename(filename);
|
||||
// Filename=filename;
|
||||
updateText();
|
||||
}
|
||||
|
||||
public String getFilename() {
|
||||
return Filename;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Image";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getN() {
|
||||
return N.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
try {
|
||||
final String Names[]=new String[P.length];
|
||||
for (int i=0; i<P.length; i++) {
|
||||
Names[i]=P[i].getName();
|
||||
}
|
||||
setText(textAny(Global.name("text.image"), Names));
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(final MyGraphics g, final ZirkelCanvas zc) {
|
||||
if (!Valid||mustHide(zc)) {
|
||||
return;
|
||||
}
|
||||
if (I==null) {
|
||||
|
||||
// I = zc.doLoadImage(Filename);
|
||||
I=Media.getImage(Filename);
|
||||
|
||||
if (I==null||I.getWidth(zc)==0||I.getHeight(zc)==0) {
|
||||
Valid=false;
|
||||
return;
|
||||
} else {
|
||||
Valid=true;
|
||||
}
|
||||
}
|
||||
if (P[1]==P[2]||P[0]==P[2]) {
|
||||
I.getWidth(zc);
|
||||
final double dx=P[1].getX()-P[0].getX(), dy=P[1].getY()
|
||||
-P[0].getY();
|
||||
g.drawImage(I, zc.col(P[0].getX()), zc.row(P[0].getY()), zc.col(P[1].getX()), zc.row(P[1].getY()), zc.col(P[0].getX()
|
||||
+dy), zc.row(P[0].getY()-dx), zc);
|
||||
} else {
|
||||
g.drawImage(I, zc.col(P[0].getX()), zc.row(P[0].getY()), zc.col(P[1].getX()), zc.row(P[1].getY()), zc.col(P[2].getX()), zc.row(P[2].getY()), zc);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int cc, final int rr, final ZirkelCanvas zc) {
|
||||
if (!displays(zc)) {
|
||||
return false;
|
||||
}
|
||||
return P[0].nearto(cc, rr, zc)||P[1].nearto(cc, rr, zc)
|
||||
||P[2].nearto(cc, rr, zc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
for (int i=0; i<P.length; i++) {
|
||||
xml.printArg("point"+(i+1), P[i].getName());
|
||||
}
|
||||
xml.printArg("filename", FileName.filename(Filename));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
DL.reset();
|
||||
for (final PointObject element : P) {
|
||||
DL.add(element);
|
||||
}
|
||||
return DL.elements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
for (int i=0; i<P.length; i++) {
|
||||
P[i]=(PointObject) P[i].getTranslation();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructionObject copy(final double x, final double y) {
|
||||
try {
|
||||
final QuadricObject o=(QuadricObject) clone();
|
||||
setTranslation(o);
|
||||
o.P=new PointObject[P.length];
|
||||
for (int i=0; i<P.length; i++) {
|
||||
o.P[i]=P[i];
|
||||
}
|
||||
o.translateConditionals();
|
||||
o.translate();
|
||||
o.setName();
|
||||
o.updateText();
|
||||
o.setBreak(false);
|
||||
o.setTarget(false);
|
||||
return o;
|
||||
} catch (final Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onlynearto(final int x, final int y, final ZirkelCanvas zc) {
|
||||
return nearto(x, y, zc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUnit() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
31
rene/zirkel/objects/InsideObject.java
Normal file
31
rene/zirkel/objects/InsideObject.java
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
|
||||
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;
|
||||
|
||||
public interface InsideObject {
|
||||
/**
|
||||
* Returns 0.5, if the point is on the boundary, and 1, if it is inside.
|
||||
*/
|
||||
public double containsInside(PointObject P);
|
||||
|
||||
public boolean keepInside(PointObject P);
|
||||
}
|
||||
291
rene/zirkel/objects/IntersectionObject.java
Normal file
291
rene/zirkel/objects/IntersectionObject.java
Normal file
|
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
659
rene/zirkel/objects/JLocusTrackObject.java
Normal file
659
rene/zirkel/objects/JLocusTrackObject.java
Normal file
|
|
@ -0,0 +1,659 @@
|
|||
/*
|
||||
|
||||
Copyright 2006 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;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
import rene.gui.Global;
|
||||
import rene.zirkel.ZirkelCanvas;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.graphics.MyGraphics;
|
||||
import rene.zirkel.graphics.PolygonDrawer;
|
||||
import rene.zirkel.structures.Coordinates;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author erichake
|
||||
*/
|
||||
public class JLocusTrackObject extends TrackObject implements HeavyObject {
|
||||
|
||||
Coordinates C;
|
||||
PolygonDrawer pd;
|
||||
double c0, r0, c, r;
|
||||
ExpressionObject EO;
|
||||
Vector RefreshList=new Vector();
|
||||
Vector DriverObjectList=new Vector();
|
||||
boolean Special=false;
|
||||
double cx, cy, ww, wh;
|
||||
long time=0;
|
||||
|
||||
public JLocusTrackObject(final Construction c, final ConstructionObject p,
|
||||
final ConstructionObject po[], final int pn,
|
||||
final ConstructionObject o, final PointObject pm) {
|
||||
|
||||
super(c);
|
||||
P=p;
|
||||
PN=pn;
|
||||
for (int i=0; i<PN; i++) {
|
||||
PO[i]=po[i];
|
||||
}
|
||||
O=o;
|
||||
PM=pm;
|
||||
validate();
|
||||
updateText();
|
||||
cx=c.getX();
|
||||
cy=c.getY();
|
||||
ww=c.getW();
|
||||
wh=c.getH();
|
||||
searchDependencies(c);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void searchDependencies(final Construction c) {
|
||||
RefreshList.clear();
|
||||
DriverObjectList.clear();
|
||||
if (O instanceof SegmentObject) {
|
||||
searchDependencies(c, this, PM);
|
||||
} else if (O instanceof ExpressionObject) {
|
||||
searchDependencies(c, this, null);
|
||||
} else if (O instanceof RayObject) {
|
||||
searchDependencies(c, this, PM);
|
||||
} else if (O instanceof PrimitiveLineObject) {
|
||||
searchDependencies(c, this, PM);
|
||||
} else if (O instanceof PrimitiveCircleObject) {
|
||||
searchDependencies(c, this, PM);
|
||||
} else if (O instanceof QuadricObject) {
|
||||
searchDependencies(c, this, PM);
|
||||
} else if (O instanceof TrackObject) {
|
||||
searchDependencies(c, this, PM);
|
||||
} else if (O instanceof AreaObject) {
|
||||
searchDependencies(c, this, PM);
|
||||
} else if (O instanceof FunctionObject) {
|
||||
searchDependencies(c, this, PM);
|
||||
}
|
||||
NeedsRecompute=true;
|
||||
}
|
||||
|
||||
public void searchDependencies(final Construction c,
|
||||
final ConstructionObject o, final ConstructionObject avoid) {
|
||||
|
||||
if (o.RekValidating) {
|
||||
return;
|
||||
} // should not happen!
|
||||
o.RekValidating=true;
|
||||
Enumeration e=c.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
((ConstructionObject) e.nextElement()).setRekFlag(false);
|
||||
}
|
||||
recursiveSearchDependencies(o, avoid);
|
||||
e=c.elements();
|
||||
|
||||
while (e.hasMoreElements()) {
|
||||
final ConstructionObject oc=(ConstructionObject) e.nextElement();
|
||||
if (oc.isRekFlag()) {
|
||||
RefreshList.addElement(oc);
|
||||
if ((!(oc==P))&&(oc.isDriverObject())) {
|
||||
DriverObjectList.addElement(oc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
o.RekValidating=false;
|
||||
}
|
||||
|
||||
public void recursiveSearchDependencies(final ConstructionObject o,
|
||||
final ConstructionObject avoid) {
|
||||
|
||||
if (o.isRekFlag()||o==avoid) {
|
||||
return;
|
||||
}
|
||||
o.setRekFlag(true);
|
||||
final ConstructionObject d[]=o.getDepArray();
|
||||
for (final ConstructionObject element : d) {
|
||||
recursiveSearchDependencies(element, avoid);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsToRecompute() {
|
||||
|
||||
boolean needs=false;
|
||||
final Enumeration pl=DriverObjectList.elements();
|
||||
while (pl.hasMoreElements()) {
|
||||
final DriverObject oc=(DriverObject) pl.nextElement();
|
||||
if (oc.somethingChanged()) {
|
||||
Global.addClearList(oc);
|
||||
// ConstructionObject oo=(ConstructionObject) oc;
|
||||
// System.out.println("needsRecompute :"+oo.getName());
|
||||
needs=true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((Cn.getX()!=cx)||(Cn.getY()!=cy)||(Cn.getW()!=ww)
|
||||
||(Cn.getH()!=wh)) {
|
||||
cx=Cn.getX();
|
||||
cy=Cn.getY();
|
||||
ww=Cn.getW();
|
||||
wh=Cn.getH();
|
||||
needs=true;
|
||||
}
|
||||
|
||||
if (NeedsRecompute) {
|
||||
NeedsRecompute=false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return needs;
|
||||
}
|
||||
|
||||
public synchronized void refresh() {
|
||||
final Enumeration e=RefreshList.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
final ConstructionObject oc=(ConstructionObject) e.nextElement();
|
||||
oc.NeedsRecompute=true;
|
||||
oc.validate();
|
||||
}
|
||||
}
|
||||
private static double a=5, b=6, xmin=-b+0.0001;
|
||||
|
||||
private static void setConstants(final Construction c) {
|
||||
final double dx=c.getW()*2;
|
||||
final double dy=c.getH();
|
||||
final double r=Math.sqrt(dx*dx+dy*dy);
|
||||
a=r;
|
||||
b=1.5*a;
|
||||
xmin=-b+(b-a)/1000;
|
||||
}
|
||||
|
||||
public static double fline(final double x) {
|
||||
if (Math.abs(x)<a) {
|
||||
return x;
|
||||
} else {
|
||||
final double s=Math.signum(x);
|
||||
return s*(2*a-b)+((b-a)*(b-a))/(s*b-x);
|
||||
}
|
||||
}
|
||||
private Coordinates oldC=new Coordinates();
|
||||
|
||||
@Override
|
||||
public void addCoordinates(final Vector v, final ConstructionObject p) {
|
||||
if (p.valid()) {
|
||||
oldC=new Coordinates(p.getX(), p.getY());
|
||||
v.addElement(oldC);
|
||||
} else {
|
||||
if (!Double.isNaN(oldC.X)) {
|
||||
oldC=new Coordinates();
|
||||
v.addElement(oldC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void docomputeCircle() {
|
||||
double dt;
|
||||
double a1;
|
||||
|
||||
final PrimitiveCircleObject CO=(PrimitiveCircleObject) O;
|
||||
final double x=CO.getX(), y=CO.getY(), RO=CO.getR();
|
||||
|
||||
if (CO.hasRange()) {
|
||||
a1=CO.getA1();
|
||||
final double a2=CO.getA2();
|
||||
double d=a2-a1;
|
||||
while (d<0) {
|
||||
d+=2*Math.PI;
|
||||
}
|
||||
while (d>=2*Math.PI) {
|
||||
d-=2*Math.PI;
|
||||
}
|
||||
dt=d*DMin;
|
||||
// I really don't understand why this is necessary for arc locuses :
|
||||
a1+=0.00000000001;
|
||||
} else {
|
||||
dt=2*Math.PI*DMin;
|
||||
a1=0;
|
||||
}
|
||||
|
||||
final int nbsteps=(int) Math.round(1/DMin)+1;
|
||||
for (int i=0; i<nbsteps; i++) {
|
||||
PM.move(x+RO*Math.cos(a1+i*dt), y+RO
|
||||
*Math.sin(a1+i*dt));
|
||||
refresh();
|
||||
addCoordinates(V, P);
|
||||
}
|
||||
|
||||
// Try to do something with points inside circle... I will see later !
|
||||
|
||||
// if (PM.isInside()) {
|
||||
// Special=true;
|
||||
// double rvar=r/nbsteps;
|
||||
// r=0;
|
||||
// for (int i=0; i<nbsteps; i++) {
|
||||
// PM.move(x+r*Math.cos(a1+i*dt), y+r*Math.sin(a1+i*dt));
|
||||
// refresh();
|
||||
// if (P.valid()) {
|
||||
// addCoordinates(V, P);
|
||||
// }
|
||||
// r+=rvar;
|
||||
// }
|
||||
// } else {
|
||||
//
|
||||
// for (int i=0; i<nbsteps; i++) {
|
||||
// PM.move(x+r*Math.cos(a1+i*dt), y+r*Math.sin(a1+i*dt));
|
||||
// refresh();
|
||||
// if (P.valid()) {
|
||||
// addCoordinates(V, P);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
public synchronized void docomputeLine() {
|
||||
Cn.shouldSwitch(false);
|
||||
final PrimitiveLineObject l=(PrimitiveLineObject) O;
|
||||
// System.out.println("zc.DX="+zc.DX+" zc.DY="+zc.DY);
|
||||
// System.out.println("dx="+Cn.getW()*2+" dy="+Cn.getH());
|
||||
setConstants(Cn);
|
||||
final double da=-2*xmin*DMin;
|
||||
final double lx=l.getX(), ly=l.getY(), ldx=l.getDX(), ldy=l.getDY();
|
||||
double delta;
|
||||
final int nbsteps=(int) Math.round(1/DMin)+1;
|
||||
for (int i=0; i<nbsteps; i++) {
|
||||
delta=fline(xmin+i*da);
|
||||
PM.move(lx+ldx*delta, ly+ldy*delta);
|
||||
refresh();
|
||||
addCoordinates(V, P);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void docomputeRay() {
|
||||
Cn.shouldSwitch(false);
|
||||
final PrimitiveLineObject l=(PrimitiveLineObject) O;
|
||||
|
||||
setConstants(Cn);
|
||||
final double da=-xmin*DMin;
|
||||
final double lx=l.getX(), ly=l.getY(), ldx=l.getDX(), ldy=l.getDY();
|
||||
double delta;
|
||||
final int nbsteps=(int) Math.round(1/DMin)+1;
|
||||
for (int i=0; i<nbsteps; i++) {
|
||||
delta=fline(i*da);
|
||||
PM.move(lx+ldx*delta, ly+ldy*delta);
|
||||
refresh();
|
||||
addCoordinates(V, P);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void docomputeSegments() {
|
||||
Cn.shouldSwitch(false);
|
||||
final PrimitiveLineObject l=(PrimitiveLineObject) O;
|
||||
final double r=((SegmentObject) l).getLength();
|
||||
final double lx=l.getX(), ly=l.getY(), ldx=r*l.getDX()*DMin, ldy=r
|
||||
*l.getDY()*DMin;
|
||||
|
||||
|
||||
final int nbsteps=(int) Math.round(1/(DMin))+1;
|
||||
|
||||
for (int i=0; i<nbsteps; i++) {
|
||||
PM.move(lx+ldx*i, ly+ldy*i);
|
||||
refresh();
|
||||
addCoordinates(V, P);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the locus of a point on conic The idea is to consider the first
|
||||
* point A of the conic (first of five points) then imagine a unit circle
|
||||
* centered on A, imagine a point B on this circle, then compute
|
||||
* intersections between line (AB) and the conic. This will give continuous
|
||||
* points set on the conic, then refresh to get the locus point.
|
||||
*
|
||||
* @param zc
|
||||
*/
|
||||
public synchronized void docomputeQuadric() {
|
||||
Cn.shouldSwitch(false);
|
||||
final QuadricObject q=(QuadricObject) O;
|
||||
|
||||
final double A=q.X[0], B=q.X[1], C=q.X[2], D=q.X[3], E=q.X[4], F=q.X[5];
|
||||
final double dt=Math.PI*DMin;
|
||||
// get the first of the five points defining the conic :
|
||||
final double X1=q.P[0].getX();
|
||||
final double Y1=q.P[0].getY();
|
||||
|
||||
double M=0, N2=0, P1=0;
|
||||
final int nbsteps=(int) Math.round(1/DMin)+1;
|
||||
// System.out.println("*******************");
|
||||
for (int i=0; i<nbsteps; i++) {
|
||||
M=-Math.sin(i*dt+0.01);
|
||||
N2=Math.cos(i*dt+0.01);
|
||||
P1=-(M*X1+N2*Y1);
|
||||
|
||||
double x1=0, x2=0, y1=0, y2=0;
|
||||
final double part1=-2*B*M*P1-C*N2*N2+D*M*N2+E
|
||||
*N2*P1;
|
||||
final double part2=Math.abs(N2)
|
||||
*Math.sqrt(-2*M*D*N2*C+4*P1*D*A*N2+4
|
||||
*P1*M*B*C+4*E*M*N2*F-2*E*P1
|
||||
*N2*C-2*E*P1*M*D-4*M*M*B*F
|
||||
-4*P1*P1*A*B-4*A*N2*N2*F+N2
|
||||
*N2*C*C+M*M*D*D+E*E*P1*P1);
|
||||
|
||||
final double part3=2*A*N2*N2+2*B*M*M+(-2*E)*M
|
||||
*N2;
|
||||
x1=(part1+part2)/part3;
|
||||
y1=(-M*x1-P1)/N2;
|
||||
x2=(part1-part2)/part3;
|
||||
y2=(-M*x2-P1)/N2;
|
||||
|
||||
if (((x2-x1)/N2)<0) {
|
||||
final double c1=x1, r1=y1;
|
||||
x1=x2;
|
||||
y1=y2;
|
||||
x2=c1;
|
||||
y2=r1;
|
||||
}
|
||||
|
||||
if ((Math.abs(X1-x1)<1e-10)&&(Math.abs(X1-x1)<1e-10)) {
|
||||
PM.move(x2, y2);
|
||||
} else {
|
||||
PM.move(x1, y1);
|
||||
}
|
||||
|
||||
refresh();
|
||||
addCoordinates(V, P);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public synchronized void docomputeExpression() {
|
||||
Cn.shouldSwitch(false);
|
||||
EO=(ExpressionObject) O;
|
||||
if (!EO.isSlider()) {
|
||||
return;
|
||||
}
|
||||
final int nbsteps=(int) Math.round(1/DMin)+1;
|
||||
double oldCursor=EO.getSliderPosition();
|
||||
for (int i=0; i<nbsteps; i++) {
|
||||
EO.setSliderPosition(DMin*i);
|
||||
refresh();
|
||||
addCoordinates(V, P);
|
||||
}
|
||||
EO.setSliderPosition(oldCursor);
|
||||
}
|
||||
|
||||
public synchronized void docomputeTrack() {
|
||||
Cn.shouldSwitch(false);
|
||||
final JLocusTrackObject TR=(JLocusTrackObject) O;
|
||||
if (DMin!=TR.DMin) {
|
||||
TR.DMin=DMin;
|
||||
TR.compute();
|
||||
}
|
||||
final Enumeration e=TR.V.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
C=(Coordinates) e.nextElement();
|
||||
PM.move(C.X, C.Y);
|
||||
refresh();
|
||||
addCoordinates(V, P);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void docomputeFunction() {
|
||||
Cn.shouldSwitch(false);
|
||||
final FunctionObject FO=(FunctionObject) O;
|
||||
final Enumeration e=FO.V.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
C=(Coordinates) e.nextElement();
|
||||
PM.move(C.X, C.Y);
|
||||
refresh();
|
||||
addCoordinates(V, P);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void docomputeArea() {
|
||||
Cn.shouldSwitch(false);
|
||||
final AreaObject poly=(AreaObject) O;
|
||||
final int NVertex=poly.V.size();
|
||||
int nbsteps=(int) Math.round(1/(DMin*NVertex));
|
||||
if (nbsteps<2) {
|
||||
nbsteps=2;
|
||||
}
|
||||
double xA, xB, yA, yB;
|
||||
final PointObject ORIGIN=(PointObject) poly.V.get(0);
|
||||
PointObject A=ORIGIN;
|
||||
PointObject B=null;
|
||||
for (int n=1; n<NVertex; n++) {
|
||||
B=(PointObject) poly.V.get(n);
|
||||
xA=A.getX();
|
||||
yA=A.getY();
|
||||
xB=B.getX();
|
||||
yB=B.getY();
|
||||
for (int i=0; i<=nbsteps; i++) {
|
||||
PM.move(xA+i*(xB-xA)/nbsteps, yA+i*(yB-yA)
|
||||
/nbsteps);
|
||||
refresh();
|
||||
addCoordinates(V, P);
|
||||
}
|
||||
A=B;
|
||||
}
|
||||
xA=A.getX();
|
||||
yA=A.getY();
|
||||
xB=ORIGIN.getX();
|
||||
yB=ORIGIN.getY();
|
||||
for (int i=0; i<=nbsteps; i++) {
|
||||
PM.move(xA+i*(xB-xA)/nbsteps, yA+i*(yB-yA)/nbsteps);
|
||||
refresh();
|
||||
addCoordinates(V, P);
|
||||
}
|
||||
|
||||
// double r=((SegmentObject) l).getLength();
|
||||
// double lx=l.getX(), ly=l.getY(), ldx=r*l.getDX()*DMin,
|
||||
// ldy=r*l.getDY()*DMin;
|
||||
//
|
||||
// int nbsteps=(int) Math.round(1/DMin)+1;
|
||||
// for (int i=0; i<nbsteps; i++) {
|
||||
// PM.move(lx+ldx*i, ly+ldy*i);
|
||||
// refresh();
|
||||
// if (P.valid()) {
|
||||
// addCoordinates(V, P);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized void compute(final ZirkelCanvas zc) {
|
||||
compute();
|
||||
}
|
||||
|
||||
public synchronized void compute() {
|
||||
if (Fixed&&!StartFix) {
|
||||
return;
|
||||
}
|
||||
|
||||
// System.out.println("compute track");
|
||||
|
||||
V=new Vector();
|
||||
oldC=new Coordinates();
|
||||
StartFix=false;
|
||||
double x=0, y=0;
|
||||
if (PM!=null) {
|
||||
x=PM.getX();
|
||||
y=PM.getY();
|
||||
}
|
||||
|
||||
Cn.clearSwitches();
|
||||
Cn.shouldSwitch(true);
|
||||
DontProject=true;
|
||||
|
||||
// Running on a segment :
|
||||
if (O instanceof SegmentObject) {
|
||||
docomputeSegments();
|
||||
// Running on a conic :
|
||||
} else if (O instanceof QuadricObject) {
|
||||
docomputeQuadric();
|
||||
// Running on an track :
|
||||
} else if (O instanceof JLocusTrackObject) {
|
||||
docomputeTrack();
|
||||
// Running on an area :
|
||||
} else if (O instanceof AreaObject) {
|
||||
docomputeArea();
|
||||
// Running on an expression :
|
||||
} else if (O instanceof ExpressionObject) {
|
||||
docomputeExpression();
|
||||
// Running on a ray :
|
||||
} else if (O instanceof RayObject) {
|
||||
docomputeRay();
|
||||
// Running on a circle :
|
||||
} else if (O instanceof PrimitiveCircleObject) {
|
||||
docomputeCircle();
|
||||
// Running on a line :
|
||||
} else if (O instanceof PrimitiveLineObject) {
|
||||
docomputeLine();
|
||||
} else if (O instanceof FunctionObject) {
|
||||
docomputeFunction();
|
||||
}
|
||||
|
||||
DontProject=false;
|
||||
// zc.getConstruction().shouldSwitch(false);
|
||||
// zc.getConstruction().clearSwitches();
|
||||
if (PM!=null) {
|
||||
PM.move(x, y);
|
||||
refresh();
|
||||
}
|
||||
|
||||
Cn.dovalidate();
|
||||
|
||||
// zc.dovalidate();
|
||||
|
||||
}
|
||||
|
||||
// public void validate() {
|
||||
// compute();
|
||||
// }
|
||||
// Paint the track
|
||||
@Override
|
||||
public void paint(final MyGraphics g, final ZirkelCanvas zc) {
|
||||
|
||||
if (!Valid||mustHide(zc)) {
|
||||
return;
|
||||
}
|
||||
Coordinates C;
|
||||
final Enumeration e=V.elements();
|
||||
double c, r;
|
||||
if (indicated()) {
|
||||
final boolean sel=P.indicated();
|
||||
P.setIndicated(true);
|
||||
g.setColor(P);
|
||||
P.setIndicated(sel);
|
||||
} else {
|
||||
g.setColor(this);
|
||||
}
|
||||
|
||||
if (Special) {
|
||||
while (e.hasMoreElements()) {
|
||||
C=(Coordinates) e.nextElement();
|
||||
PointObject.drawPoint(g, zc, this, C.X, C.Y, Type);
|
||||
}
|
||||
} else {
|
||||
final PolygonDrawer pd=new PolygonDrawer(false,g, this);
|
||||
|
||||
if (e.hasMoreElements()) {
|
||||
|
||||
C=(Coordinates) e.nextElement();
|
||||
c0=zc.col(C.X);
|
||||
r0=zc.row(C.Y);
|
||||
pd.startPolygon(c0, r0);
|
||||
|
||||
}
|
||||
|
||||
while (e.hasMoreElements()) {
|
||||
C=(Coordinates) e.nextElement();
|
||||
c=zc.col(C.X);
|
||||
r=zc.row(C.Y);
|
||||
if (Math.abs(pd.c()-c)<1000&&Math.abs(pd.r()-r)<1000) {
|
||||
pd.drawTo(c, r);
|
||||
} else {
|
||||
pd.finishPolygon();
|
||||
pd.startPolygon(c, r);
|
||||
}
|
||||
}
|
||||
|
||||
pd.finishPolygon();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpecial() {
|
||||
return Special;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpecial(final boolean f) {
|
||||
Special=f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final ConstructionObject o) {
|
||||
if (!(o instanceof JLocusTrackObject)||!o.valid()) {
|
||||
return false;
|
||||
}
|
||||
JLocusTrackObject loc=(JLocusTrackObject) o;
|
||||
if (V.size()!=loc.V.size()) {
|
||||
return false;
|
||||
}
|
||||
final Enumeration e1=V.elements();
|
||||
final Enumeration e2=loc.V.elements();
|
||||
while (e1.hasMoreElements()) {
|
||||
Coordinates C1=(Coordinates) e1.nextElement();
|
||||
Coordinates C2=(Coordinates) e2.nextElement();
|
||||
if ((Math.abs(C1.X-C2.X)>1e-8)||Math.abs(C1.Y-C2.Y)>1e-8) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructionObject copy(final double x, final double y) {
|
||||
PointObject newPM=null;
|
||||
if (PM!=null) {
|
||||
newPM=(PointObject) PM.getTranslation();
|
||||
}
|
||||
|
||||
final JLocusTrackObject jl=new JLocusTrackObject(Cn.getTranslation(),
|
||||
P.getTranslation(), PO, PN, O.getTranslation(), newPM);
|
||||
jl.setTargetDefaults();
|
||||
return jl;
|
||||
}
|
||||
// public void translate() {
|
||||
// if (PM!=null) {
|
||||
// PM=(PointObject) PM.getTranslation();
|
||||
// }
|
||||
//
|
||||
// O=O.getTranslation();
|
||||
// P=P.getTranslation();
|
||||
//
|
||||
// searchDependencies(Cn.getTranslation());
|
||||
// }
|
||||
}
|
||||
115
rene/zirkel/objects/LineCircleIntersectionObject.java
Normal file
115
rene/zirkel/objects/LineCircleIntersectionObject.java
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
|
||||
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: LineCircleIntersectionObject.java
|
||||
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.structures.Coordinates;
|
||||
|
||||
public class LineCircleIntersectionObject extends IntersectionObject {
|
||||
public LineCircleIntersectionObject(final Construction c,
|
||||
final PrimitiveLineObject P1, final PrimitiveCircleObject P2,
|
||||
final boolean first) {
|
||||
super(c, P1, P2);
|
||||
First = first;
|
||||
validate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCircleDep() {
|
||||
((PrimitiveCircleObject) P2).addDep(this);
|
||||
((PrimitiveLineObject) P1).addDep(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
final boolean oldvalid = Valid;
|
||||
if (!P1.valid() || !P2.valid())
|
||||
Valid = false;
|
||||
else
|
||||
Valid = true;
|
||||
if (!Valid)
|
||||
return;
|
||||
final Coordinates c = PrimitiveLineObject.intersect(
|
||||
(PrimitiveLineObject) P1, (PrimitiveCircleObject) P2);
|
||||
if (c == null) {
|
||||
if (oldvalid && getConstruction().shouldSwitch()) {
|
||||
doSwitch();
|
||||
if (!getConstruction().noteSwitch())
|
||||
Switched = false;
|
||||
} else if (oldvalid && Alternate && Away == null
|
||||
&& getConstruction().canAlternate()) {
|
||||
First = !First;
|
||||
}
|
||||
Valid = false;
|
||||
return;
|
||||
}
|
||||
if (getAway() != null) {
|
||||
final double x = getAway().getX(), y = getAway().getY();
|
||||
final double r = (x - c.X) * (x - c.X) + (y - c.Y) * (y - c.Y);
|
||||
final double r1 = (x - c.X1) * (x - c.X1) + (y - c.Y1) * (y - c.Y1);
|
||||
boolean flag = (r > r1);
|
||||
if (!StayAway)
|
||||
flag = !flag;
|
||||
if (flag) {
|
||||
setXY(c.X, c.Y);
|
||||
} else {
|
||||
setXY(c.X1, c.Y1);
|
||||
}
|
||||
} else {
|
||||
if (First) {
|
||||
setXY(c.X, c.Y);
|
||||
} else {
|
||||
setXY(c.X1, c.Y1);
|
||||
}
|
||||
}
|
||||
if (Restricted) {
|
||||
if (!((PrimitiveLineObject) P1).contains(X, Y))
|
||||
Valid = false;
|
||||
if (!(((PrimitiveCircleObject) P2).getStart() == this || ((PrimitiveCircleObject) P2)
|
||||
.getEnd() == this)
|
||||
&& !((PrimitiveCircleObject) P2).contains(X, Y))
|
||||
Valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
super.printArgs(xml);
|
||||
if (First)
|
||||
xml.printArg("which", "first");
|
||||
else
|
||||
xml.printArg("which", "second");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSwitchable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAlternate() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
222
rene/zirkel/objects/LineIntersectionObject.java
Normal file
222
rene/zirkel/objects/LineIntersectionObject.java
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
|
||||
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;
|
||||
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.structures.Coordinates;
|
||||
|
||||
// file: IntersectionObject.java
|
||||
|
||||
public class LineIntersectionObject extends IntersectionObject {
|
||||
public LineIntersectionObject(final Construction c,
|
||||
final PrimitiveLineObject P1, final PrimitiveLineObject P2) {
|
||||
super(c, P1, P2);
|
||||
validate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCircleDep() {
|
||||
((PrimitiveLineObject) P1).addDep(this);
|
||||
((PrimitiveLineObject) P2).addDep(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
if(!P1.valid() || !P2.valid()) {
|
||||
Valid = false;
|
||||
} else {
|
||||
Valid = true;
|
||||
}
|
||||
|
||||
if(!Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Coordinates coord = PrimitiveLineObject.intersect((PrimitiveLineObject) P1, (PrimitiveLineObject) P2);
|
||||
|
||||
if(coord == null) {
|
||||
Valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
setXY(coord.X, coord.Y);
|
||||
if(Restricted) {
|
||||
if (!((PrimitiveLineObject) P1).contains(X, Y))
|
||||
Valid = false;
|
||||
else if(!((PrimitiveLineObject) P2).contains(X, Y)) {
|
||||
Valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* En 3D
|
||||
*
|
||||
* On veut résoudre le système : (dans le membre de gauche l'équation de P1, dans celui de droite, l'équation de P2)
|
||||
* x1 + a1s = x2 + a2t
|
||||
* y1 + b1s = y2 + b2t
|
||||
* z1 + c1s = z2 + c2t
|
||||
*
|
||||
* où (x1;y1;z1) est un point de P1 et (x2;y2;z2) un point de P2
|
||||
* et (a1;b1;c1) est un vd de P1 et (a2;b2;c2) est un vd de P2
|
||||
*
|
||||
* Ce système est équivalent à :
|
||||
* a1s - a2t = x2 - x1 (L1)
|
||||
* b1s - b2t = y2 - y1 (L2)
|
||||
* c1s - c2t = z2 - z1 (L3)
|
||||
*/
|
||||
|
||||
try {
|
||||
if(((PrimitiveLineObject) P1).getP1().is3D() && ((PrimitiveLineObject) P2).getP1().is3D()) {
|
||||
double x1 = ((PrimitiveLineObject) P1).getP1().getX3D();
|
||||
double y1 = ((PrimitiveLineObject) P1).getP1().getY3D();
|
||||
double z1 = ((PrimitiveLineObject) P1).getP1().getZ3D();
|
||||
|
||||
double x2 = ((PrimitiveLineObject) P2).getP1().getX3D();
|
||||
double y2 = ((PrimitiveLineObject) P2).getP1().getY3D();
|
||||
double z2 = ((PrimitiveLineObject) P2).getP1().getZ3D();
|
||||
|
||||
/**
|
||||
* Si P2 ou P2 sont des parallèles, la méthode Pi.getP2() ne renvoie rien.
|
||||
* Pour connaitre un vecteur directeur de P1, il suffit de connaitre
|
||||
* sa parallèle, instance de TwoPointLineObject
|
||||
*/
|
||||
ConstructionObject p1 = P1;
|
||||
if(p1 instanceof ParallelObject) {
|
||||
do{
|
||||
p1 = ((ParallelObject) p1).getL();
|
||||
} while(!(p1 instanceof TwoPointLineObject));
|
||||
}
|
||||
double a1 = ((TwoPointLineObject) p1).getP2().getX3D() - ((TwoPointLineObject) p1).getP1().getX3D();
|
||||
double b1 = ((TwoPointLineObject) p1).getP2().getY3D() - ((TwoPointLineObject) p1).getP1().getY3D();
|
||||
double c1 = ((TwoPointLineObject) p1).getP2().getZ3D() - ((TwoPointLineObject) p1).getP1().getZ3D();
|
||||
|
||||
ConstructionObject p2 = P2;
|
||||
if(p2 instanceof ParallelObject) {
|
||||
do{
|
||||
p2 = ((ParallelObject) p2).getL();
|
||||
} while(!(p2 instanceof TwoPointLineObject));
|
||||
}
|
||||
double a2 = ((TwoPointLineObject) p2).getP2().getX3D() - ((TwoPointLineObject) p2).getP1().getX3D();
|
||||
double b2 = ((TwoPointLineObject) p2).getP2().getY3D() - ((TwoPointLineObject) p2).getP1().getY3D();
|
||||
double c2 = ((TwoPointLineObject) p2).getP2().getZ3D() - ((TwoPointLineObject) p2).getP1().getZ3D();
|
||||
|
||||
//(L1) et (L2)
|
||||
double det = -a1*b2 + b1*a2;
|
||||
double dets = -(x2-x1)*b2 + (y2-y1)*a2;
|
||||
double dett = a1*(y2-y1) - b1*(x2-x1);
|
||||
int choice = 1;
|
||||
|
||||
if(Math.abs(det)<1e-12) { //(L1) et (L3)
|
||||
det = -a1*c2 + c1*a2;
|
||||
dets = -(x2-x1)*c2 + (z2-z1)*a2;
|
||||
dett = a1*(z2-z1) - c1*(x2-x1);
|
||||
choice = 2;
|
||||
}
|
||||
if(Math.abs(det)<1e-12) { //(L2) et (L3)
|
||||
det = -b1*c2 + c1*b2;
|
||||
dets = -(y2-y1)*c2 + (z2-z1)*b2;
|
||||
dett = b1*(z2-z1) - c1*(y2-y1);
|
||||
choice = 3;
|
||||
}
|
||||
|
||||
double s = dets/det, t = dett/det;
|
||||
|
||||
if ( (choice==1 && Math.abs(c1*s-c2*t-z2+z1)<1e-12)
|
||||
|| (choice==2 && Math.abs(b1*s-b2*t-y2+y1)<1e-12)
|
||||
|| (choice==3 && Math.abs(a1*s-a2*t-x2+x1)<1e-12)) {
|
||||
setX3D(x1+a1*s);
|
||||
setY3D(y1+b1*s);
|
||||
setZ3D(z1+c1*s);
|
||||
setIs3D(true);
|
||||
//System.out.println(x1+a1*s);
|
||||
//System.out.println(y1+b1*s);
|
||||
//System.out.println(z1+c1*s);
|
||||
//System.out.println("-------");
|
||||
setSuperHidden(false);
|
||||
} else {
|
||||
setSuperHidden(true);
|
||||
}
|
||||
}
|
||||
} catch(final Exception ex){}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
if( (P1 instanceof TwoPointLineObject && ((TwoPointLineObject) P1).getP1().is3D())
|
||||
|| (P1 instanceof TwoPointLineObject && ((TwoPointLineObject) P1).getP2().is3D())
|
||||
|| (P2 instanceof TwoPointLineObject && ((TwoPointLineObject) P2).getP1().is3D())
|
||||
|| (P2 instanceof TwoPointLineObject && ((TwoPointLineObject) P2).getP2().is3D())) {
|
||||
try { // Dibs intersection 3D
|
||||
double a1=((TwoPointLineObject) P1).getP1().getX3D();
|
||||
double b1=((TwoPointLineObject) P1).getP1().getY3D();
|
||||
double c1=((TwoPointLineObject) P1).getP1().getZ3D();
|
||||
double a2=((TwoPointLineObject) P1).getP2().getX3D();
|
||||
double b2=((TwoPointLineObject) P1).getP2().getY3D();
|
||||
double c2=((TwoPointLineObject) P1).getP2().getZ3D();
|
||||
|
||||
double a3=((TwoPointLineObject) P2).getP1().getX3D();
|
||||
double b3=((TwoPointLineObject) P2).getP1().getY3D();
|
||||
double c3=((TwoPointLineObject) P2).getP1().getZ3D();
|
||||
double a4=((TwoPointLineObject) P2).getP2().getX3D();
|
||||
double b4=((TwoPointLineObject) P2).getP2().getY3D();
|
||||
double c4=((TwoPointLineObject) P2).getP2().getZ3D();
|
||||
|
||||
double det =(a2-a1)*(b3-b4)+(b2-b1)*(a4-a3);
|
||||
double dets=(b3-b1)*(a4-a3)-(a3-a1)*(b4-b3);
|
||||
double dett=(a2-a1)*(b3-b1)-(b2-b1)*(a3-a1);
|
||||
int choice = 1;
|
||||
|
||||
if(Math.abs(det)<1e-12) {
|
||||
det =(b2-b1)*(c3-c4)+(c2-c1)*(b4-b3);
|
||||
dets=(c3-c1)*(b4-b3)-(b3-b1)*(c4-c3);
|
||||
dett=(b2-b1)*(c3-c1)-(c2-c1)*(b3-b1);
|
||||
choice = 2;
|
||||
}
|
||||
if(Math.abs(det)<1e-12) {
|
||||
det =(a2-a1)*(c3-c4)+(c2-c1)*(a4-a3);
|
||||
dets=(a3-a1)*(c3-c4)+(c3-c1)*(a4-a3);
|
||||
dett=(a2-a1)*(c3-c1)-(c2-c1)*(a3-a1);
|
||||
choice = 3;
|
||||
}
|
||||
|
||||
double s, t;
|
||||
s=dets/det;
|
||||
t=dett/det;
|
||||
|
||||
if ( (choice==1 && Math.abs((c2-c1)*s-(c4-c3)*t-c3+c1)<1e-12)
|
||||
|| (choice==2 && Math.abs((b2-b1)*s-(b4-b3)*t-b3+b1)<1e-12)
|
||||
|| (choice==3 && Math.abs((a2-a1)*s-(a4-a3)*t-a3+a1)<1e-12)) {
|
||||
setX3D(a1+s*(a2-a1));
|
||||
setY3D(b1+s*(b2-b1));
|
||||
setZ3D(c1+s*(c2-c1));
|
||||
setIs3D(true);
|
||||
setSuperHidden(false);
|
||||
} else {
|
||||
setSuperHidden(true);
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
//System.err.println("Error : "+ex);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
193
rene/zirkel/objects/LineObject.java
Normal file
193
rene/zirkel/objects/LineObject.java
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
|
||||
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: LineObject.java
|
||||
|
||||
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.graphics.MyGraphics;
|
||||
import rene.zirkel.graphics.MainGraphics;
|
||||
|
||||
public class LineObject extends TwoPointLineObject {
|
||||
static Count N = new Count();
|
||||
|
||||
public LineObject(final Construction c, final PointObject p1,
|
||||
final PointObject p2) {
|
||||
super(c, p1, p2);
|
||||
validate();
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Line";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
setText(text2(Global.name("text.line"), P1.getName(), P2.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
if (!P1.valid() || !P2.valid()) {
|
||||
Valid = false;
|
||||
return;
|
||||
} else {
|
||||
Valid = true;
|
||||
X1 = P1.getX();
|
||||
Y1 = P1.getY();
|
||||
X2 = P2.getX();
|
||||
Y2 = P2.getY();
|
||||
// compute normalized vector in the direction of the line:
|
||||
DX = X2 - X1;
|
||||
DY = Y2 - Y1;
|
||||
R = Math.sqrt(DX * DX + DY * DY);
|
||||
if (R < 1e-10) {
|
||||
Valid = false;
|
||||
return;
|
||||
}
|
||||
DX /= R;
|
||||
DY /= R;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(final MyGraphics g, final ZirkelCanvas zc) {
|
||||
if (!Valid || mustHide(zc))
|
||||
return;
|
||||
if (!Partial || zc.showHidden()) {
|
||||
super.paint(g, zc);
|
||||
return;
|
||||
}
|
||||
// compute middle of the screen:
|
||||
final double xm = (zc.minX() + zc.maxX()) / 2, ym = (zc.minY() + zc
|
||||
.maxY()) / 2;
|
||||
// compute distance from middle to line:
|
||||
final double d = (xm - X1) * DY - (ym - Y1) * DX;
|
||||
// compute point with minimal distance
|
||||
final double x = xm - d * DY, y = ym + d * DX;
|
||||
// compute size of the screen
|
||||
final double a = Math.max(zc.maxX() - zc.minX(), zc.maxY() - zc.minY());
|
||||
if (Math.abs(d) > a)
|
||||
return;
|
||||
// compute distance from closest point to source
|
||||
final double b = (x - X1) * DX + (y - Y1) * DY;
|
||||
// compute the two visible endpoints
|
||||
k1 = b - a;
|
||||
k2 = b + a;
|
||||
k12valid = true;
|
||||
final double dd = (zc.maxX() - zc.minX()) / 20;
|
||||
double dmin = -dd, dmax = R + dd;
|
||||
if (Dep != null) {
|
||||
for (int i = 0; i < NDep; i++) {
|
||||
if (!Dep[i].valid() || Dep[i].mustHide(zc))
|
||||
continue;
|
||||
final double s = project(Dep[i].getX(), Dep[i].getY());
|
||||
if (s - dd < dmin)
|
||||
dmin = s - dd;
|
||||
else if (s + dd > dmax)
|
||||
dmax = s + dd;
|
||||
}
|
||||
}
|
||||
if (k1 < dmin)
|
||||
k1 = dmin;
|
||||
if (k2 > dmax)
|
||||
k2 = dmax;
|
||||
final double c1 = zc.col(X1 + k1 * DX), c2 = zc.col(X1 + k2 * DX), r1 = zc
|
||||
.row(Y1 + k1 * DY), r2 = zc.row(Y1 + k2 * DY);
|
||||
// paint:
|
||||
if (isStrongSelected() && g instanceof MainGraphics) {
|
||||
((MainGraphics) g).drawMarkerLine(c1, r1, c2, r2);
|
||||
}
|
||||
g.setColor(this);
|
||||
g.drawLine(c1, r1, c2, r2, this);
|
||||
final String s = getDisplayText();
|
||||
if (!s.equals("")) {
|
||||
g.setLabelColor(this);
|
||||
setFont(g);
|
||||
DisplaysText = true;
|
||||
if (KeepClose) {
|
||||
final double side = (YcOffset < 0) ? 1 : -1;
|
||||
drawLabel(g, s, zc, X1 + XcOffset * DX, Y1 + XcOffset * DY,
|
||||
side * DX, side * DY, 0, 0);
|
||||
} else
|
||||
drawLabel(g, s, zc, X1 + k2 * DX / 2, Y1 + k2 * DY / 2, DX, DY,
|
||||
XcOffset, YcOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
xml.printArg("from", P1.getName());
|
||||
xml.printArg("to", P2.getName());
|
||||
super.printArgs(xml);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaults() {
|
||||
super.setDefaults();
|
||||
setPartial(Cn.PartialLines);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toggleHidden() {
|
||||
if (Hidden) {
|
||||
Partial = false;
|
||||
Hidden = false;
|
||||
} else {
|
||||
if (Partial) {
|
||||
Partial = false;
|
||||
Hidden = true;
|
||||
} else
|
||||
Partial = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUnit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int c, final int r, final ZirkelCanvas zc) {
|
||||
if (!displays(zc))
|
||||
return false;
|
||||
if (zc.showHidden() || !Partial || Dep == null || !k12valid)
|
||||
return super.nearto(c, r, zc);
|
||||
// compute point at c,r
|
||||
final double x = zc.x(c), y = zc.y(r);
|
||||
// test, if on visible part
|
||||
final double s = project(x, y);
|
||||
if (s < k1 || s > k2)
|
||||
return false;
|
||||
// compute distance from x,y
|
||||
final double d = (x - X1) * DY - (y - Y1) * DX;
|
||||
// scale in screen coordinates
|
||||
Value = Math.abs(zc.col(zc.minX() + d) - zc.col(zc.minX()));
|
||||
return Value < zc.selectionSize() * 2;
|
||||
}
|
||||
}
|
||||
268
rene/zirkel/objects/LineQuadricIntersectionObject.java
Normal file
268
rene/zirkel/objects/LineQuadricIntersectionObject.java
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
/*
|
||||
|
||||
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: LineCircleIntersectionObject.java
|
||||
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.structures.Coordinates;
|
||||
|
||||
public class LineQuadricIntersectionObject extends IntersectionObject {
|
||||
|
||||
public LineQuadricIntersectionObject(final Construction c,
|
||||
final PrimitiveLineObject P1, final QuadricObject P2,
|
||||
final boolean first) {
|
||||
super(c, P1, P2);
|
||||
First = first;
|
||||
validate();
|
||||
}
|
||||
|
||||
// public void updateCircleDep ()
|
||||
// { ((QuadricObject)P2).addDep(this);
|
||||
// ((PrimitiveLineObject)P1).addDep(this);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
final boolean oldvalid = Valid;
|
||||
if (!P1.valid() || !P2.valid())
|
||||
Valid = false;
|
||||
else
|
||||
Valid = true;
|
||||
if (!Valid)
|
||||
return;
|
||||
final Coordinates c = PrimitiveLineObject.intersect(
|
||||
(PrimitiveLineObject) P1, (QuadricObject) P2);
|
||||
|
||||
if (c == null) {
|
||||
if (oldvalid && getConstruction().shouldSwitch()) {
|
||||
doSwitch();
|
||||
if (!getConstruction().noteSwitch())
|
||||
Switched = false;
|
||||
} else if (oldvalid && Alternate && Away == null
|
||||
&& getConstruction().canAlternate()) {
|
||||
First = !First;
|
||||
}
|
||||
Valid = false;
|
||||
return;
|
||||
}
|
||||
double X1, Y1;
|
||||
if (getAway() != null) {
|
||||
final double x = getAway().getX(), y = getAway().getY();
|
||||
final double r = (x - c.X) * (x - c.X) + (y - c.Y) * (y - c.Y);
|
||||
final double r1 = (x - c.X1) * (x - c.X1) + (y - c.Y1) * (y - c.Y1);
|
||||
boolean flag = (r > r1);
|
||||
if (!StayAway)
|
||||
flag = !flag;
|
||||
if (flag) {
|
||||
setXY(c.X, c.Y);
|
||||
X1 = c.X1;
|
||||
Y1 = c.Y1;
|
||||
} else {
|
||||
setXY(c.X1, c.Y1);
|
||||
X1 = c.X;
|
||||
Y1 = c.Y;
|
||||
}
|
||||
} else {
|
||||
if (First) {
|
||||
setXY(c.X, c.Y);
|
||||
X1 = c.X1;
|
||||
Y1 = c.Y1;
|
||||
} else {
|
||||
setXY(c.X1, c.Y1);
|
||||
X1 = c.X;
|
||||
Y1 = c.Y;
|
||||
}
|
||||
}
|
||||
if (Restricted) {
|
||||
|
||||
if (!((PrimitiveLineObject) P1).contains(X, Y)) {
|
||||
if (!((PrimitiveLineObject) P1).contains(X1, Y1)) {
|
||||
Valid = false;
|
||||
} else {
|
||||
setXY(X1, Y1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if (P1 instanceof TwoPointLineObject&&(((TwoPointLineObject) P1).getP1().is3D()||((TwoPointLineObject) P1).getP2().is3D())
|
||||
||((QuadricObject) P2).getP()[0].is3D()||((QuadricObject) P2).getP()[1].is3D()||((QuadricObject) P2).getP()[2].is3D()||((QuadricObject) P2).getP()[3].is3D()||((QuadricObject) P2).getP()[4].is3D()) {
|
||||
TwoPointLineObject ligne= (TwoPointLineObject) P1;
|
||||
try {
|
||||
double x1=((PointObject) ligne.getP1()).getX3D();
|
||||
double y1=((PointObject) ligne.getP1()).getY3D();
|
||||
double z1=((PointObject) ligne.getP1()).getZ3D();
|
||||
double x2=((PointObject) ligne.getP2()).getX3D();
|
||||
double y2=((PointObject) ligne.getP2()).getY3D();
|
||||
double z2=((PointObject) ligne.getP2 ()).getZ3D();
|
||||
double x_O=getConstruction().find("O").getX();
|
||||
double x_X=getConstruction().find("X").getX();
|
||||
double x_Y=getConstruction().find("Y").getX();
|
||||
double x_Z=getConstruction().find("Z").getX();
|
||||
double alpha1=(getX()-x_O-x1*(x_X-x_O)-y1*(x_Y-x_O)-z1*(x_Z-x_O))/((x2-x1)*(x_X-x_O)+(y2-y1)*(x_Y-x_O)+(z2-z1)*(x_Z-x_O));
|
||||
if (x1==x2&&y1==y2) {
|
||||
double y_O=getConstruction().find("O").getY();
|
||||
double y_X=getConstruction().find("X").getY();
|
||||
double y_Y=getConstruction().find("Y").getY();
|
||||
double y_Z=getConstruction().find("Z").getY();
|
||||
alpha1=(getY()-y_O-x1*(y_X-y_O)-y1*(y_Y-y_O)-z1*(y_Z-y_O))/((x2-x1)*(y_X-y_O)+(y2-y1)*(y_Y-y_O)+(z2-z1)*(y_Z-y_O));
|
||||
}
|
||||
final double xM=x1+alpha1*(x2-x1);
|
||||
final double yM=y1+alpha1*(y2-y1);
|
||||
final double zM=z1+alpha1*(z2-z1);
|
||||
setX3D(xM);
|
||||
setY3D(yM);
|
||||
setZ3D(zM);
|
||||
setIs3D(true);
|
||||
//setFixed("x(O)+("+xM+")*(x(X)-x(O))+("+yM+")*(x(Y)-x(O))+("+z1+zM+")*(x(Z)-x(O))", "y(O)+("+xM+")*(y(X)-y(O))+("+yM+")*(y(Y)-y(O))+("+zM+")*(y(Z)-y(O))");
|
||||
} catch (final Exception eBary) {
|
||||
}
|
||||
// si les intersections n'existent pas en 3D, on les rendra superhidden
|
||||
try {
|
||||
boolean isGood=false;
|
||||
double a1=((QuadricObject) P2).getP()[0].getX3D();
|
||||
double b1=((QuadricObject) P2).getP()[0].getY3D();
|
||||
double c1=((QuadricObject) P2).getP()[0].getZ3D();
|
||||
double a2=((QuadricObject) P2).getP()[1].getX3D();
|
||||
double b2=((QuadricObject) P2).getP()[1].getY3D();
|
||||
double c2=((QuadricObject) P2).getP()[1].getZ3D();
|
||||
double a3=((QuadricObject) P2).getP()[2].getX3D();
|
||||
double b3=((QuadricObject) P2).getP()[2].getY3D();
|
||||
double c3=((QuadricObject) P2).getP()[2].getZ3D();
|
||||
double a4=(a1+a2)/2, b4=(b1+b2)/2, c4=(c1+c2)/2;
|
||||
double a5=(a1+a3)/2, b5=(b1+b3)/2, c5=(c1+c3)/2;
|
||||
double a6=a2-a1, b6=b2-b1, c6=c2-c1;
|
||||
double a7=a3-a1, b7=b3-b1, c7=c3-c1;
|
||||
double a8=b6*c7-c6*b7, b8=c6*a7-a6*c7, c8=a6*b7-b6*a7;
|
||||
double n8=Math.sqrt(a8*a8+b8*b8+c8*c8);
|
||||
a8 /=n8; b8 /= n8; c8 /= n8; // on norme P8
|
||||
double a9=b8*c6-c8*b6, b9=c8*a6-a8*c6, c9=a8*b6-b8*a6;
|
||||
double a10=b7*c8-c7*b8, b10=c7*a8-a7*c8, c10=a7*b8-b7*a8;
|
||||
double a11=a5-a4, b11=b5-b4, c11=c5-c4;
|
||||
double det1=b9*a10-a9*b10;
|
||||
double det2=a10*b11-b10*a11;
|
||||
double a12=a4+det2/det1*a9, b12=b4+det2/det1*b9, c12=c4+det2/det1*c9; // centre
|
||||
double rcarre=(a12-a1)*(a12-a1)+(b12-b1)*(b12-b1)+(c12-c1)*(c12-c1); //rayon^2
|
||||
double a15=((PointObject) ligne.getP1()).getX3D();
|
||||
double b15=((PointObject) ligne.getP1()).getY3D();
|
||||
double c15=((PointObject) ligne.getP1()).getZ3D();
|
||||
double a16=((PointObject) ligne.getP2()).getX3D();
|
||||
double b16=((PointObject) ligne.getP2()).getY3D();
|
||||
double c16=((PointObject) ligne.getP2 ()).getZ3D();
|
||||
double a17=a16-a15, b17=b16-b15, c17=c16-c15;
|
||||
double a18=a15-a12, b18=b15-b12, c18=c15-c12;
|
||||
try {
|
||||
double x3=-(Math.sqrt((c17*c17+b17*b17+a17*a17)*rcarre+(-b17*b17-a17*a17)*c18*c18+(2*b17*b18+2*a17*a18)*c17*c18+(-b18*b18-a18*a18)*c17*c17-a17*a17*b18*b18+2*a17*a18*b17*b18-a18*a18*b17*b17)+c17*c18+b17*b18+a17*a18)/(c17*c17+b17*b17+a17*a17);
|
||||
double x4=(Math.sqrt((c17*c17+b17*b17+a17*a17)*rcarre+(-b17*b17-a17*a17)*c18*c18+(2*b17*b18+2*a17*a18)*c17*c18+(-b18*b18-a18*a18)*c17*c17-a17*a17*b18*b18+2*a17*a18*b17*b18-a18*a18*b17*b17)-c17*c18-b17*b18-a17*a18)/(c17*c17+b17*b17+a17*a17);
|
||||
double a19=a15+x3*a17, b19=b15+x3*b17, c19=c15+x3*c17; // soluces potentielles
|
||||
double a20=a15+x4*a17, b20=b15+x4*b17, c20=c15+x4*c17;
|
||||
double a21=a19-a1, b21=b19-b1, c21=c19-c1;
|
||||
double a22=a20-a1, b22=b20-b1, c22=c20-c1;
|
||||
double pscal19 =a8*a21+b8*b21+c8*c21;
|
||||
double pscal20 =a8*a22+b8*b22+c8*c22;
|
||||
if (Math.abs(pscal19)<1e-8) { // OK pour P19
|
||||
final double xO=getConstruction().find("O").getX();
|
||||
final double yO=getConstruction().find("O").getY();
|
||||
final double deltaxX=getConstruction().find("X").getX()-xO;
|
||||
final double deltaxY=getConstruction().find("Y").getX()-xO;
|
||||
final double deltaxZ=getConstruction().find("Z").getX()-xO;
|
||||
final double deltayX=getConstruction().find("X").getY()-yO;
|
||||
final double deltayY=getConstruction().find("Y").getY()-yO;
|
||||
final double deltayZ=getConstruction().find("Z").getY()-yO;
|
||||
double posx=xO+a19*deltaxX+b19*deltaxY+c19*deltaxZ; // coordonnées 2D
|
||||
double posy=yO+a19*deltayX+b19*deltayY+c19*deltayZ;
|
||||
double erreurcarre=(c.X-posx)*(c.X-posx)+(c.Y-posy)*(c.Y-posy);
|
||||
double erreurcarre2=(c.X1-posx)*(c.X1-posx)+(c.Y1-posy)*(c.Y1-posy);
|
||||
if (erreurcarre<1e-8||erreurcarre2<1e-8) {
|
||||
isGood=true;
|
||||
setX3D(a19);
|
||||
setY3D(b19);
|
||||
setZ3D(c19);
|
||||
}
|
||||
else if (Math.abs(pscal20)<1e-8) {
|
||||
posx=xO+a20*deltaxX+b20*deltaxY+c20*deltaxZ; // coordonnées 2D
|
||||
posy=yO+a20*deltayX+b20*deltayY+c20*deltayZ;
|
||||
erreurcarre=(c.X-posx)*(c.X-posx)+(c.Y-posy)*(c.Y-posy);
|
||||
erreurcarre2=(c.X1-posx)*(c.X1-posx)+(c.Y1-posy)*(c.Y1-posy);
|
||||
if (erreurcarre<1e-8||erreurcarre2<1e-8) {
|
||||
isGood=true;
|
||||
setX3D(a20);
|
||||
setY3D(b20);
|
||||
setZ3D(c20);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Math.abs(pscal20)<1e-8) { // OK pour P20
|
||||
final double xO=getConstruction().find("O").getX();
|
||||
final double yO=getConstruction().find("O").getY();
|
||||
final double deltaxX=getConstruction().find("X").getX()-xO;
|
||||
final double deltaxY=getConstruction().find("Y").getX()-xO;
|
||||
final double deltaxZ=getConstruction().find("Z").getX()-xO;
|
||||
final double deltayX=getConstruction().find("X").getY()-yO;
|
||||
final double deltayY=getConstruction().find("Y").getY()-yO;
|
||||
final double deltayZ=getConstruction().find("Z").getY()-yO;
|
||||
double posx=xO+a20*deltaxX+b20*deltaxY+c20*deltaxZ; // coordonnées 2D
|
||||
double posy=yO+a20*deltayX+b20*deltayY+c20*deltayZ;
|
||||
double erreurcarre=(c.X-posx)*(c.X-posx)+(c.Y-posy)*(c.Y-posy);
|
||||
double erreurcarre2=(c.X1-posx)*(c.X1-posx)+(c.Y1-posy)*(c.Y1-posy);
|
||||
if (erreurcarre<1e-8||erreurcarre2<1e-8) {
|
||||
isGood=true;
|
||||
setX3D(a20);
|
||||
setY3D(b20);
|
||||
setZ3D(c20);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final Exception ex) {
|
||||
//setSuperHidden(true);
|
||||
}
|
||||
if (!isGood) {
|
||||
setSuperHidden(true);
|
||||
}
|
||||
}
|
||||
|
||||
catch (final Exception ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
super.printArgs(xml);
|
||||
if (First)
|
||||
xml.printArg("which", "first");
|
||||
else
|
||||
xml.printArg("which", "second");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSwitchable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAlternate() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
121
rene/zirkel/objects/MidpointObject.java
Normal file
121
rene/zirkel/objects/MidpointObject.java
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
|
||||
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: MidpointObject.java
|
||||
|
||||
import java.util.Enumeration;
|
||||
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.gui.Global;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.construction.Count;
|
||||
|
||||
public class MidpointObject extends PointObject {
|
||||
PointObject P1, P2;
|
||||
static Count N = new Count();
|
||||
|
||||
public MidpointObject(final Construction c, final PointObject p1,
|
||||
final PointObject p2) {
|
||||
super(c, 0, 0);
|
||||
P1 = p1;
|
||||
P2 = p2;
|
||||
Moveable = false;
|
||||
validate();
|
||||
updateText();
|
||||
}
|
||||
|
||||
// public void setName ()
|
||||
// {
|
||||
//
|
||||
// if (Cn.LongNames)
|
||||
// Name=Global.name("name."+getTag())+" "+getN();
|
||||
// else
|
||||
// Name=Global.name("name.short."+getTag())+getN();
|
||||
// // System.out.println("nom="+Name);
|
||||
//
|
||||
// }
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Midpoint";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getN() {
|
||||
return N.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
try {
|
||||
setText(text2(Global.name("text.midpoint"), P1.getName(), P2
|
||||
.getName()));
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
if (!P1.valid() || !P2.valid())
|
||||
Valid = false;
|
||||
else {
|
||||
Valid = true;
|
||||
setXY((P1.getX() + P2.getX()) / 2, (P1.getY() + P2.getY()) / 2);
|
||||
if (P1.is3D()&&P2.is3D()) {
|
||||
setXYZ((P1.getX3D() + P2.getX3D()) / 2, (P1.getY3D() + P2.getY3D()) / 2, (P1.getZ3D() + P2.getZ3D()) / 2);
|
||||
setIs3D(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
xml.printArg("first", P1.getName());
|
||||
xml.printArg("second", P2.getName());
|
||||
printType(xml);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
super.depending();
|
||||
DL.add(P1);
|
||||
DL.add(P2);
|
||||
return DL.elements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
P1 = (PointObject) P1.getTranslation();
|
||||
P2 = (PointObject) P2.getTranslation();
|
||||
}
|
||||
|
||||
public PointObject getP1() {
|
||||
return P1;
|
||||
}
|
||||
|
||||
public PointObject getP2() {
|
||||
return P2;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
38
rene/zirkel/objects/MoveableObject.java
Normal file
38
rene/zirkel/objects/MoveableObject.java
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
|
||||
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;
|
||||
|
||||
public interface MoveableObject {
|
||||
public void move(double x, double y);
|
||||
|
||||
public void startDrag(double x, double y);
|
||||
|
||||
public void dragTo(double x, double y);
|
||||
|
||||
// public boolean hasChanged();
|
||||
public double getOldX();
|
||||
|
||||
public double getOldY();
|
||||
|
||||
public boolean moveable();
|
||||
|
||||
}
|
||||
150
rene/zirkel/objects/ParallelObject.java
Normal file
150
rene/zirkel/objects/ParallelObject.java
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
|
||||
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: ParallelObject.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;
|
||||
|
||||
public class ParallelObject extends PrimitiveLineObject implements
|
||||
MoveableObject {
|
||||
protected PrimitiveLineObject L;
|
||||
static Count N = new Count();
|
||||
|
||||
public ParallelObject(final Construction c, final PrimitiveLineObject l,
|
||||
final PointObject p) {
|
||||
super(c);
|
||||
P1 = p;
|
||||
L = l;
|
||||
validate();
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Parallel";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getN() {
|
||||
return N.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
setText(text2(Global.name("text.parallel"), P1.getName(), L.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
if (!P1.valid() || !L.valid())
|
||||
Valid = false;
|
||||
else if (L instanceof SegmentObject
|
||||
&& ((SegmentObject) L).getLength() == 0) {
|
||||
Valid = false;
|
||||
} else {
|
||||
Valid = true;
|
||||
X1 = P1.getX();
|
||||
Y1 = P1.getY();
|
||||
DX = L.getDX();
|
||||
DY = L.getDY();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
xml.printArg("point", P1.getName());
|
||||
xml.printArg("line", L.getName());
|
||||
super.printArgs(xml);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
super.depending();
|
||||
return depset(P1, L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
P1 = (PointObject) P1.getTranslation();
|
||||
L = (PrimitiveLineObject) L.getTranslation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(final PointObject p) {
|
||||
return p == P1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUnit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void dragTo(final double x, final double y) {
|
||||
P1.move(x1 + (x - x3), y1 + (y - y3));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(final double x, final double y) {
|
||||
}
|
||||
|
||||
public boolean moveable() {
|
||||
if (P1.moveable())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
double x1, y1, x2, y2, x3, y3;
|
||||
|
||||
public void startDrag(final double x, final double y) {
|
||||
x1 = P1.getX();
|
||||
y1 = P1.getY();
|
||||
x3 = x;
|
||||
y3 = y;
|
||||
}
|
||||
|
||||
public double getOldX() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double getOldY() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void snap(final ZirkelCanvas zc) {
|
||||
if (moveable()) {
|
||||
P1.snap(zc);
|
||||
}
|
||||
}
|
||||
|
||||
public PrimitiveLineObject getL(){
|
||||
return L;
|
||||
}
|
||||
|
||||
}
|
||||
175
rene/zirkel/objects/PlumbObject.java
Normal file
175
rene/zirkel/objects/PlumbObject.java
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
|
||||
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: PlumbObject.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;
|
||||
|
||||
public class PlumbObject extends PrimitiveLineObject implements MoveableObject {
|
||||
PrimitiveLineObject L;
|
||||
static Count N = new Count();
|
||||
protected boolean Restricted = false;
|
||||
|
||||
public PlumbObject(final Construction c, final PrimitiveLineObject l,
|
||||
final PointObject p) {
|
||||
super(c);
|
||||
P1 = p;
|
||||
L = l;
|
||||
validate();
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Plumb";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getN() {
|
||||
return N.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
setText(text2(Global.name("text.plumb"), P1.getName(), L.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
if (!P1.valid() || !L.valid())
|
||||
Valid = false;
|
||||
else {
|
||||
Valid = true;
|
||||
X1 = P1.getX();
|
||||
Y1 = P1.getY();
|
||||
DX = -L.getDY();
|
||||
DY = L.getDX();
|
||||
if (L instanceof SegmentObject
|
||||
&& ((SegmentObject) L).getLength() == 0) {
|
||||
Valid = false;
|
||||
}
|
||||
if (Restricted) {
|
||||
if (!L.contains(X1, Y1))
|
||||
Valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
xml.printArg("point", P1.getName());
|
||||
xml.printArg("line", L.getName());
|
||||
if (!Restricted)
|
||||
xml.printArg("valid", "true");
|
||||
super.printArgs(xml);
|
||||
}
|
||||
|
||||
public boolean isRestricted() {
|
||||
return Restricted;
|
||||
}
|
||||
|
||||
public void setRestricted(final boolean flag) {
|
||||
Restricted = flag;
|
||||
}
|
||||
|
||||
public boolean canRestrict() {
|
||||
return (L instanceof SegmentObject) || (L instanceof RayObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMainParameter(boolean b) {
|
||||
MainParameter = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
super.depending();
|
||||
return depset(P1, L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
P1 = (PointObject) P1.getTranslation();
|
||||
L = (PrimitiveLineObject) L.getTranslation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(final PointObject p) {
|
||||
return p == P1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUnit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void dragTo(final double x, final double y) {
|
||||
P1.move(x1 + (x - x3), y1 + (y - y3));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(final double x, final double y) {
|
||||
}
|
||||
|
||||
public boolean moveable() {
|
||||
if (P1.moveable()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
double x1, y1, x2, y2, x3, y3;
|
||||
|
||||
public void startDrag(final double x, final double y) {
|
||||
x1 = P1.getX();
|
||||
y1 = P1.getY();
|
||||
x3 = x;
|
||||
y3 = y;
|
||||
}
|
||||
|
||||
public double getOldX() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double getOldY() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void snap(final ZirkelCanvas zc) {
|
||||
if (moveable()) {
|
||||
P1.snap(zc);
|
||||
}
|
||||
}
|
||||
|
||||
public PrimitiveLineObject getL(){
|
||||
return L;
|
||||
}
|
||||
|
||||
}
|
||||
1748
rene/zirkel/objects/PointObject.java
Normal file
1748
rene/zirkel/objects/PointObject.java
Normal file
File diff suppressed because it is too large
Load diff
32
rene/zirkel/objects/PointonObject.java
Normal file
32
rene/zirkel/objects/PointonObject.java
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
|
||||
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;
|
||||
|
||||
public interface PointonObject {
|
||||
public void repulse(PointObject P);
|
||||
|
||||
public void project(PointObject P);
|
||||
|
||||
public void project(PointObject P, double alpha);
|
||||
|
||||
public boolean canInteresectWith(ConstructionObject o);
|
||||
}
|
||||
237
rene/zirkel/objects/PointonObjectIntersectionObject.java
Normal file
237
rene/zirkel/objects/PointonObjectIntersectionObject.java
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
|
||||
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;
|
||||
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.expression.Secant;
|
||||
|
||||
/**
|
||||
* An intersection between two object that can bind points on them. The
|
||||
* intersection is computed by projecting the point to both objects and
|
||||
* predicting the intersection point.
|
||||
*
|
||||
* @author Rene
|
||||
*/
|
||||
public class PointonObjectIntersectionObject extends IntersectionObject {
|
||||
|
||||
public double Eps = 1e-5;
|
||||
private boolean xAxisFunctionIntersection = false,
|
||||
yAxisFunctionIntersection = false;
|
||||
private FunctionObject F = null;
|
||||
|
||||
public PointonObjectIntersectionObject(final Construction c,
|
||||
final ConstructionObject p1, final ConstructionObject p2) {
|
||||
super(c, p1, p2);
|
||||
if ((p1 instanceof AxisObject) && (p2 instanceof FunctionObject)) {
|
||||
|
||||
F = (FunctionObject) p2;
|
||||
if (F.getEX().toString().equals("x")) {
|
||||
final AxisObject ax = ((AxisObject) p1);
|
||||
if (ax.DX == 1) {
|
||||
xAxisFunctionIntersection = true;
|
||||
} else {
|
||||
yAxisFunctionIntersection = true;
|
||||
}
|
||||
}
|
||||
|
||||
} else if ((p2 instanceof AxisObject) && (p1 instanceof FunctionObject)) {
|
||||
F = (FunctionObject) p1;
|
||||
if (F.getEX().toString().equals("x")) {
|
||||
final AxisObject ax = ((AxisObject) p2);
|
||||
if (ax.DX == 1) {
|
||||
xAxisFunctionIntersection = true;
|
||||
} else {
|
||||
yAxisFunctionIntersection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(final double x, final double y) {
|
||||
setXY(x, y);
|
||||
validate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
xml.printArg("first", P1.getName());
|
||||
xml.printArg("second", P2.getName());
|
||||
xml.printArg("x", "" + getX());
|
||||
xml.printArg("y", "" + getY());
|
||||
if (getAway() != null) {
|
||||
if (StayAway) {
|
||||
xml.printArg("awayfrom", getAway().getName());
|
||||
} else {
|
||||
xml.printArg("closeto", getAway().getName());
|
||||
}
|
||||
}
|
||||
printType(xml);
|
||||
if (!Restricted) {
|
||||
xml.printArg("valid", "true");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Troublesome function to intersect two objects. This is done by projecting
|
||||
* the intersection point to each of the objects in turn.
|
||||
*
|
||||
* To speed up the convergence, a line intersection is computed, where the
|
||||
* lines approximate the objects.
|
||||
*/
|
||||
@Override
|
||||
public void validate() {
|
||||
// if ((P1==null)||(P2==null)) {
|
||||
// System.out.println(this.getName());
|
||||
// }
|
||||
|
||||
if (!P1.valid() || !P2.valid()) {
|
||||
Valid = false;
|
||||
} else {
|
||||
Valid = true;
|
||||
}
|
||||
if (!Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (yAxisFunctionIntersection) {
|
||||
try {
|
||||
setXY(0, F.evaluateF(0));
|
||||
return;
|
||||
} catch (final Exception ex) {
|
||||
}
|
||||
}
|
||||
|
||||
if (xAxisFunctionIntersection) {
|
||||
try {
|
||||
|
||||
double xn = 0;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
double distold = projectOnce();
|
||||
if (!Valid) {
|
||||
return;
|
||||
}
|
||||
final double dist1 = projectOnce();
|
||||
if (dist1 >= distold && dist1 < Eps) {
|
||||
break;
|
||||
}
|
||||
distold = dist1;
|
||||
double a = x1 - x;
|
||||
double b = y1 - y;
|
||||
double s = Math.max(Math.abs(a), Math.abs(b));
|
||||
if (Math.abs(s) > 1e-13) {
|
||||
a /= s;
|
||||
}
|
||||
b /= s;
|
||||
double c = X - x1;
|
||||
double d = Y - y1;
|
||||
s = Math.max(Math.abs(c), Math.abs(d));
|
||||
if (Math.abs(s) > 1e-13) {
|
||||
c /= s;
|
||||
}
|
||||
d /= s;
|
||||
final double e = a * x1 + b * y1;
|
||||
final double f = c * X + d * Y;
|
||||
final double det = a * d - c * b;
|
||||
if (Math.abs(det) > 1e-13) {
|
||||
xn = (e * d - f * b) / det;
|
||||
final double dist2 = projectOnce();
|
||||
if (dist2 < dist1) {
|
||||
distold = dist2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setXY(Secant.compute(F, xn - 1e-1, xn + 1e-1, 1e-10), 0);
|
||||
|
||||
return;
|
||||
} catch (final Exception ex) {
|
||||
}
|
||||
}
|
||||
|
||||
double distold = projectOnce();
|
||||
if (!Valid) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
final double dist1 = projectOnce();
|
||||
if (dist1 >= distold && dist1 < Eps) {
|
||||
return;
|
||||
}
|
||||
distold = dist1;
|
||||
double a = (x1 - x), b = (y1 - y);
|
||||
double s = Math.max(Math.abs(a), Math.abs(b));
|
||||
if (Math.abs(s) > 1e-13) {
|
||||
a /= s;
|
||||
}
|
||||
b /= s;
|
||||
double c = (X - x1), d = (Y - y1);
|
||||
s = Math.max(Math.abs(c), Math.abs(d));
|
||||
if (Math.abs(s) > 1e-13) {
|
||||
c /= s;
|
||||
}
|
||||
d /= s;
|
||||
final double e = a * x1 + b * y1, f = c * X + d * Y;
|
||||
final double det = a * d - c * b;
|
||||
if (Math.abs(det) > 1e-13) {
|
||||
final double xn = (e * d - f * b) / det;
|
||||
final double yn = (a * f - c * e) / det;
|
||||
final double xold = X, yold = Y;
|
||||
setXY(xn, yn);
|
||||
final double dist2 = projectOnce();
|
||||
if (dist2 > dist1) // interpolation does not work
|
||||
{
|
||||
setXY(xold, yold);
|
||||
} else {
|
||||
distold = dist2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Valid = false;
|
||||
}
|
||||
|
||||
double x, y, x1, y1;
|
||||
|
||||
public double projectOnce() {
|
||||
x = X;
|
||||
y = Y;
|
||||
// System.out.println("Before: "+X+" "+Y);
|
||||
((PointonObject) P1).project(this);
|
||||
// System.out.println("Projected to "+P1.getName()+": "+X+" "+Y);
|
||||
final double dist = Math.max(Math.abs(X - x), Math.abs(Y - y));
|
||||
x1 = X;
|
||||
y1 = Y;
|
||||
((PointonObject) P2).project(this);
|
||||
// System.out.println("Projected to "+P2.getName()+": "+X+" "+Y);
|
||||
final double dist1 = Math.max(Math.abs(X - x1), Math.abs(Y - y1));
|
||||
return Math.max(dist, dist1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveable() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
988
rene/zirkel/objects/PrimitiveCircleObject.java
Normal file
988
rene/zirkel/objects/PrimitiveCircleObject.java
Normal file
|
|
@ -0,0 +1,988 @@
|
|||
/*
|
||||
|
||||
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: PrimitiveCircleObject.java
|
||||
import java.awt.Color;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.Enumeration;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import rene.gui.Global;
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.zirkel.ZirkelCanvas;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.construction.Count;
|
||||
import rene.zirkel.expression.Expression;
|
||||
import rene.zirkel.expression.ExpressionColor;
|
||||
import rene.zirkel.graphics.MyGraphics;
|
||||
import rene.zirkel.graphics.MainGraphics;
|
||||
import rene.zirkel.structures.Coordinates;
|
||||
|
||||
public class PrimitiveCircleObject extends ConstructionObject implements
|
||||
PointonObject, InsideObject {
|
||||
|
||||
protected double X, Y, R;
|
||||
static Count N=new Count();
|
||||
boolean Partial=false;
|
||||
PointObject Dep[]; // array for points, depending on the circle for partial
|
||||
// display
|
||||
int NDep; // number of points in Dep
|
||||
PointObject M; // The midpoint
|
||||
boolean Filled=false;
|
||||
String StartPtName=null, EndPtName=null; // Border points name for Arcs
|
||||
PointObject StartPt=null, EndPt=null; // Border points for Arcs
|
||||
// PointObject RealCorrespondingStartPt=null; // for 3 pts Arcs only
|
||||
boolean isArc3pts=false;
|
||||
double A1, A2, A;
|
||||
boolean Arc=true;
|
||||
// Seulement pour les droites hyperboliques :
|
||||
private double oldStartX=Double.NaN;
|
||||
private double oldStartY=Double.NaN;
|
||||
|
||||
public PrimitiveCircleObject(final Construction c, final PointObject p) {
|
||||
super(c);
|
||||
setColor(ColorIndex, SpecialColor);
|
||||
M=p;
|
||||
Unit=Global.getParameter("unit.length", "");
|
||||
}
|
||||
|
||||
public void validate() {
|
||||
super.validate();
|
||||
// Gestion de la continuité des droites sur le cercle horizon :
|
||||
if (isDPLineObject()) {
|
||||
// Premier passage, mémorisation de l'extrémité Start de l'arc
|
||||
if (Double.isNaN(oldStartX)) {
|
||||
oldStartX=getStart().getX();
|
||||
oldStartY=getStart().getY();
|
||||
} else {
|
||||
final double d1=(oldStartX-getStart().getX())*(oldStartX-getStart().getX())
|
||||
+(oldStartY-getStart().getY())*(oldStartY-getStart().getY());
|
||||
final double d2=(oldStartX-getEnd().getX())*(oldStartX-getEnd().getX())
|
||||
+(oldStartY-getEnd().getY())*(oldStartY-getEnd().getY());
|
||||
// Si Start et End se sont échangés, on remet dans l'ordre (cela fonctionne
|
||||
// car ce sont des arcs 180°) :
|
||||
if (d2<d1) {
|
||||
PointObject P=StartPt;
|
||||
StartPt=EndPt;
|
||||
EndPt=P;
|
||||
}
|
||||
oldStartX=getStart().getX();
|
||||
oldStartY=getStart().getY();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setMR(final PointObject p1, final double r) {
|
||||
M=p1;
|
||||
R=r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaults() {
|
||||
|
||||
setShowName(Global.getParameter("options.circle.shownames", false));
|
||||
setShowValue(Global.getParameter("options.circle.showvalues", false));
|
||||
|
||||
setColor(Global.getParameter("options.circle.color", 0), Global.getParameter("options.circle.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.circle.colortype", 0));
|
||||
setFilled(Global.getParameter("options.circle.filled", false));
|
||||
setSolid(Global.getParameter("options.circle.solid", false));
|
||||
setHidden(Cn.Hidden);
|
||||
setObtuse(Cn.Obtuse);
|
||||
// setSolid(Cn.Solid);
|
||||
setLarge(Cn.LargeFont);
|
||||
setBold(Cn.BoldFont);
|
||||
setPartial(Cn.Partial);
|
||||
Cn.updateCircleDep();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetDefaults() {
|
||||
if (isDPLineObject()) {
|
||||
setShowName(Global.getParameter("options.line.shownames", false));
|
||||
setShowValue(Global.getParameter("options.line.showvalues", false));
|
||||
setColor(Global.getParameter("options.line.color", 0), Global.getParameter("options.line.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.line.colortype", 0));
|
||||
setFilled(Global.getParameter("options.line.filled", false));
|
||||
setSolid(Global.getParameter("options.line.solid", false));
|
||||
} else if (isDPSegmentObject()) {
|
||||
setShowName(Global.getParameter("options.segment.shownames", false));
|
||||
setShowValue(Global.getParameter("options.segment.showvalues", false));
|
||||
setColor(Global.getParameter("options.segment.color", 0), Global.getParameter("options.segment.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.segment.colortype", 0));
|
||||
setFilled(Global.getParameter("options.segment.filled", false));
|
||||
setSolid(Global.getParameter("options.segment.solid", false));
|
||||
} else {
|
||||
setShowName(Global.getParameter("options.circle.shownames", false));
|
||||
setShowValue(Global.getParameter("options.circle.showvalues", false));
|
||||
setColor(Global.getParameter("options.circle.color", 0), Global.getParameter("options.circle.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.circle.colortype", 0));
|
||||
setFilled(Global.getParameter("options.circle.filled", false));
|
||||
setSolid(Global.getParameter("options.circle.solid", false));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Circle";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getN() {
|
||||
return N.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(final MyGraphics g, final ZirkelCanvas zc) {
|
||||
|
||||
|
||||
if (!Valid||mustHide(zc)) {
|
||||
return;
|
||||
}
|
||||
final double c1=zc.col(X-R), c2=zc.col(X+R), r1=zc.row(Y+R), r2=zc.row(Y-R), r=(r2-r1)/2;
|
||||
double ssa=1/Math.sqrt(2), ssb=-ssa;
|
||||
// paint:
|
||||
|
||||
if (!zc.showHidden()&&Dep!=null&&NDep>0&&Partial
|
||||
&&!hasRange()) // partial display
|
||||
{
|
||||
|
||||
// System.out.println("partial display");
|
||||
for (int i=0; i<NDep; i++) {
|
||||
if (!Dep[i].valid()
|
||||
||((!zc.isPreview())&&(Dep[i].mustHide(zc)))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
double A=Math.atan2(Dep[i].getY()-Y, Dep[i].getX()-X);
|
||||
if (A<0) {
|
||||
A+=2*Math.PI;
|
||||
}
|
||||
final double a=A/Math.PI*180;
|
||||
if (visible(zc)) {
|
||||
|
||||
if (isStrongSelected()&&g instanceof MainGraphics) {
|
||||
((MainGraphics) g).drawMarkerArc((c1+c2)/2.0,
|
||||
(r1+r2)/2.0, r, a-10, 20);
|
||||
}
|
||||
g.setColor(this);
|
||||
g.drawCircleArc(c1+r, r1+r, r, a-10, 20, this);
|
||||
}
|
||||
if (i==0) {
|
||||
final String s=getDisplayText();
|
||||
if (!s.equals("")) {
|
||||
g.setLabelColor(this);
|
||||
DisplaysText=true;
|
||||
final double sx=Math.cos(A-0.1);
|
||||
final double sy=Math.sin(A-0.1);
|
||||
drawLabel(g, s, zc, X+sx*R, Y+sy*R, sy, -sx,
|
||||
XcOffset, YcOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (hasRange()) // arc display
|
||||
{
|
||||
computeSOE();
|
||||
if (visible(zc)) {
|
||||
if (isStrongSelected()&&g instanceof MainGraphics) {
|
||||
((MainGraphics) g).drawMarkerArc((c1+c2)/2.0,
|
||||
(r1+r2)/2.0, r, A1/Math.PI*180, A
|
||||
/Math.PI*180);
|
||||
}
|
||||
g.setColor(this);
|
||||
if (Filled) {
|
||||
g.fillArc(c1, r1, c2-c1, r2-r1, A1/Math.PI*180,
|
||||
A/Math.PI*180, Selected
|
||||
||(getColorType()!=THIN),
|
||||
getColorType()!=THICK, Arc, this);
|
||||
} else if (visible(zc)) {
|
||||
g.drawCircleArc(c1+r, r1+r, r, A1/Math.PI*180,
|
||||
A/Math.PI*180, this);
|
||||
}
|
||||
}
|
||||
ssa=Math.cos(A1+A/2);
|
||||
ssb=Math.sin(A1+A/2);
|
||||
} else if (Filled) {
|
||||
if (visible(zc)) {
|
||||
if (isStrongSelected()&&g instanceof MainGraphics) {
|
||||
((MainGraphics) g).drawMarkerArc((c1+c2)/2.0,
|
||||
(r1+r2)/2.0, r, 0, 360);
|
||||
}
|
||||
g.setColor(this);
|
||||
g.fillOval(c1, r1, c2-c1, r2-r1, Indicated||Selected
|
||||
||(getColorType()==NORMAL),
|
||||
getColorType()!=THICK, this);
|
||||
}
|
||||
} else // full unfilled display
|
||||
{
|
||||
if (visible(zc)) {
|
||||
if (isStrongSelected()&&g instanceof MainGraphics) {
|
||||
((MainGraphics) g).drawMarkerArc((c1+c2)/2.0,
|
||||
(r1+r2)/2.0, r, 0, 360);
|
||||
}
|
||||
g.setColor(this);
|
||||
if (tracked()) {
|
||||
zc.UniversalTrack.drawTrackCircle(this, c1+r, r1+r,
|
||||
r);
|
||||
}
|
||||
g.drawCircle(c1+r, r1+r, r, this);
|
||||
}
|
||||
}
|
||||
final String s=getDisplayText();
|
||||
if (!s.equals("")) {
|
||||
g.setLabelColor(this);
|
||||
DisplaysText=true;
|
||||
drawLabel(g, s, zc, X+ssa*R, Y+ssb*R, -ssa, ssb,
|
||||
XcOffset, YcOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayValue() {
|
||||
// return ""+round(R,ZirkelCanvas.LengthsFactor);
|
||||
return Global.getLocaleNumber(R, "lengths");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEquation() {
|
||||
return "(x"+helpDisplayNumber(false, -X)+")^2+"+"(y"
|
||||
+helpDisplayNumber(false, -Y)+")^2="
|
||||
+helpDisplayNumber(true, R*R);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInRect(Rectangle r, ZirkelCanvas zc) {
|
||||
double Xest=M.getX()+getR(), Yest=M.getY();
|
||||
double Xnord=M.getX(), Ynord=M.getY()+getR();
|
||||
double Xouest=M.getX()-getR(), Youest=M.getY();
|
||||
double Xsud=M.getX(), Ysud=M.getY()-getR();
|
||||
|
||||
boolean b=r.contains(zc.col(Xest), zc.row(Yest));
|
||||
b=b&&r.contains(zc.col(Xnord), zc.row(Ynord));
|
||||
b=b&&r.contains(zc.col(Xouest), zc.row(Youest));
|
||||
b=b&&r.contains(zc.col(Xsud), zc.row(Ysud));
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int c, final int r, final ZirkelCanvas zc) {
|
||||
return nearto(c, r, false, zc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int c, final int r, final boolean ignorefill,
|
||||
final ZirkelCanvas zc) {
|
||||
if (!displays(zc)) {
|
||||
return false;
|
||||
}
|
||||
final double x=zc.x(c)-X, y=zc.y(r)-Y;
|
||||
if (!ignorefill&&Filled) {
|
||||
final double d=Math.sqrt(x*x+y*y);
|
||||
if (d<R) {
|
||||
Value=0;
|
||||
}
|
||||
return d<R;
|
||||
} else if (hasRange()) {
|
||||
computeSOE();
|
||||
double a=Math.atan2(y, x);
|
||||
if (a<0) {
|
||||
a+=2*Math.PI;
|
||||
}
|
||||
a-=A1;
|
||||
if (a<0) {
|
||||
a+=2*Math.PI;
|
||||
}
|
||||
final double d=Math.abs(Math.sqrt(x*x+y*y)-R);
|
||||
if (a<=A+0.01) {
|
||||
Value=Math.abs(zc.col(zc.minX()+d)-zc.col(zc.minX()));
|
||||
}
|
||||
return Value<zc.selectionSize()&&a<=A+0.01;
|
||||
} // partial display:
|
||||
else if (!zc.showHidden()&&NDep>0&&Partial) {
|
||||
double d=Math.abs(Math.sqrt(x*x+y*y)-R);
|
||||
Value=Math.abs(zc.col(zc.minX()+d)-zc.col(zc.minX()));
|
||||
if (Math.abs(zc.col(zc.minX()+d)-zc.col(zc.minX()))>=zc.selectionSize()) {
|
||||
return false;
|
||||
}
|
||||
d=Math.PI/18;
|
||||
double a=Math.atan2(y, x);
|
||||
if (a<0) {
|
||||
a+=2*Math.PI;
|
||||
}
|
||||
for (int i=0; i<NDep; i++) {
|
||||
if (!Dep[i].valid()||Dep[i].mustHide(zc)) {
|
||||
continue;
|
||||
}
|
||||
double A=Math.atan2(Dep[i].getY()-Y, Dep[i].getX()-X);
|
||||
if (A<0) {
|
||||
A+=2*Math.PI;
|
||||
}
|
||||
double h=a-A;
|
||||
if (h>2*Math.PI) {
|
||||
h-=2*Math.PI;
|
||||
}
|
||||
if (h<-2*Math.PI) {
|
||||
h+=2*Math.PI;
|
||||
}
|
||||
if (Math.abs(h)<d) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
final double d=Math.abs(Math.sqrt(x*x+y*y)-R);
|
||||
Value=Math.abs(zc.col(zc.minX()+d)-zc.col(zc.minX()));
|
||||
return Math.abs(zc.col(zc.minX()+d)-zc.col(zc.minX()))<zc.selectionSize();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onlynearto(final int c, final int r, final ZirkelCanvas zc) {
|
||||
if (R<zc.dx(3*zc.pointSize())) {
|
||||
return true;
|
||||
}
|
||||
if (hasRange()) {
|
||||
double A1=Math.atan2(getStart().getY()-Y, getStart().getX()-X);
|
||||
if (A1<0) {
|
||||
A1+=2*Math.PI;
|
||||
}
|
||||
double A2=Math.atan2(getEnd().getY()-Y, getEnd().getX()-X);
|
||||
if (A2<0) {
|
||||
A2+=2*Math.PI;
|
||||
}
|
||||
double A=A2-A1;
|
||||
if (A>=2*Math.PI) {
|
||||
A-=2*Math.PI;
|
||||
}
|
||||
if (A<0) {
|
||||
A+=2*Math.PI;
|
||||
}
|
||||
if (!Obtuse&&A>Math.PI) {
|
||||
A1=A2;
|
||||
A=2*Math.PI-A;
|
||||
A2=A1+A;
|
||||
}
|
||||
if (A*R<zc.dx(6*zc.pointSize())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getX() {
|
||||
return X;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getY() {
|
||||
return Y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getR() {
|
||||
return R;
|
||||
}
|
||||
|
||||
public static Coordinates intersect(final PrimitiveCircleObject c1,
|
||||
final PrimitiveCircleObject c2) {
|
||||
double dx=c2.X-c1.X, dy=c2.Y-c1.Y;
|
||||
final double r=Math.sqrt(dx*dx+dy*dy);
|
||||
if (r>c1.R+c2.R+1e-10) {
|
||||
return null;
|
||||
}
|
||||
if (r<=1e-10) {
|
||||
return new Coordinates(c1.X, c1.Y, c1.X, c1.Y);
|
||||
}
|
||||
final double l=(r*r+c1.R*c1.R-c2.R*c2.R)/(2*r);
|
||||
dx/=r;
|
||||
dy/=r;
|
||||
final double x=c1.X+l*dx, y=c1.Y+l*dy;
|
||||
double h=c1.R*c1.R-l*l;
|
||||
if (h<-1e-10) {
|
||||
return null;
|
||||
}
|
||||
if (h<0) {
|
||||
h=0;
|
||||
} else {
|
||||
h=Math.sqrt(h);
|
||||
}
|
||||
return new Coordinates(x+h*dy, y-h*dx, x-h*dy, y+h*dx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final ConstructionObject o) {
|
||||
if (!(o instanceof PrimitiveCircleObject)||!o.valid()) {
|
||||
return false;
|
||||
}
|
||||
final PrimitiveCircleObject l=(PrimitiveCircleObject) o;
|
||||
return equals(X, l.X)&&equals(Y, l.Y)&&equals(R, l.R);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPartial(final boolean flag) {
|
||||
if (flag==Partial) {
|
||||
return;
|
||||
}
|
||||
Partial=flag;
|
||||
if (flag) // depending objects no longer needed
|
||||
{
|
||||
Dep=new PointObject[16];
|
||||
NDep=0;
|
||||
} else {
|
||||
Dep=null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a point that depends on the circle. Dep is used for partial display.
|
||||
*
|
||||
* @param p
|
||||
*/
|
||||
public void addDep(final PointObject p) {
|
||||
if (!Partial||hasRange()||Dep==null||NDep>=Dep.length) {
|
||||
return;
|
||||
}
|
||||
Dep[NDep++]=p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCircleDep() {
|
||||
NDep=0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPartial() {
|
||||
return Partial;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
xml.printArg("midpoint", M.getName());
|
||||
if (Partial) {
|
||||
xml.printArg("partial", "true");
|
||||
}
|
||||
if (Filled) {
|
||||
xml.printArg("filled", "true");
|
||||
}
|
||||
if (getStart()!=null) {
|
||||
xml.printArg("start", getStart().getName());
|
||||
}
|
||||
if (getEnd()!=null) {
|
||||
xml.printArg("end", getEnd().getName());
|
||||
}
|
||||
if (!Obtuse) {
|
||||
xml.printArg("acute", "true");
|
||||
}
|
||||
if (!Arc) {
|
||||
xml.printArg("chord", "true");
|
||||
}
|
||||
super.printArgs(xml);
|
||||
}
|
||||
|
||||
/**
|
||||
* Need to setup the Dep array.
|
||||
*/
|
||||
@Override
|
||||
public ConstructionObject copy(final double x, final double y) {
|
||||
final PrimitiveCircleObject o=(PrimitiveCircleObject) super.copy(0, 0);
|
||||
if (o.Partial) {
|
||||
o.Dep=new PointObject[16];
|
||||
o.NDep=0;
|
||||
} else {
|
||||
o.Dep=null;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
// public void setDefaults ()
|
||||
// { super.setDefaults();
|
||||
// setPartial(Cn.Partial);
|
||||
// }
|
||||
/**
|
||||
* A circle depends on its midpoint at least. Other circles depen on more
|
||||
* points! No circle depends on Start and End.
|
||||
*/
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
super.depending();
|
||||
DL.add(M);
|
||||
return DL.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* A circle will mark the midpoint as secondary parameter.
|
||||
*/
|
||||
@Override
|
||||
public Enumeration secondaryParams() {
|
||||
DL.reset();
|
||||
return depset(M);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toggleHidden() {
|
||||
if (Hidden) {
|
||||
Hidden=false;
|
||||
} else {
|
||||
if (Partial) {
|
||||
setPartial(false);
|
||||
Hidden=true;
|
||||
} else {
|
||||
setPartial(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PointObject getP1() {
|
||||
return M;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilled(final boolean flag) {
|
||||
Filled=flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFilled() {
|
||||
return Filled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFilledForSelect() {
|
||||
return Filled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
M=(PointObject) M.getTranslation();
|
||||
if (hasRange()) {
|
||||
StartPt=(PointObject) StartPt.getTranslation();
|
||||
EndPt=(PointObject) EndPt.getTranslation();
|
||||
StartPtName=StartPt.getName();
|
||||
EndPtName=EndPt.getName();
|
||||
}
|
||||
}
|
||||
|
||||
public void setRange(final String s1, final String s2) {
|
||||
StartPtName=s1;
|
||||
EndPtName=s2;
|
||||
setRange((PointObject) Cn.find(StartPtName), (PointObject) Cn.find(EndPtName));
|
||||
}
|
||||
|
||||
public void setRange(PointObject p1, PointObject p2) {
|
||||
StartPt=p1;
|
||||
EndPt=p2;
|
||||
}
|
||||
|
||||
public PointObject getStart() {
|
||||
if ((StartPt==null)&&(StartPtName!=null)) {
|
||||
StartPt=(PointObject) Cn.find(StartPtName);
|
||||
}
|
||||
return StartPt;
|
||||
}
|
||||
|
||||
public PointObject getEnd() {
|
||||
if ((EndPt==null)&&(EndPtName!=null)) {
|
||||
EndPt=(PointObject) Cn.find(EndPtName);
|
||||
}
|
||||
return EndPt;
|
||||
}
|
||||
|
||||
public double getA1() {
|
||||
return A1;
|
||||
}
|
||||
|
||||
public double getA2() {
|
||||
return A2;
|
||||
}
|
||||
|
||||
public boolean hasRange() {
|
||||
return getStart()!=null&&getEnd()!=null;
|
||||
}
|
||||
|
||||
public void clearRange() {
|
||||
StartPt=EndPt=null;
|
||||
StartPtName=EndPtName=null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean maybeTransparent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean locallyLike(final ConstructionObject o) {
|
||||
if (!(o instanceof PrimitiveCircleObject)) {
|
||||
return false;
|
||||
}
|
||||
return (equals(X, ((PrimitiveCircleObject) o).X)
|
||||
&&equals(Y, ((PrimitiveCircleObject) o).Y)&&equals(R,
|
||||
((PrimitiveCircleObject) o).R));
|
||||
}
|
||||
|
||||
public boolean getArc() {
|
||||
return Arc;
|
||||
}
|
||||
|
||||
public void setArc(final boolean flag) {
|
||||
Arc=flag;
|
||||
}
|
||||
|
||||
public void detectArc3Pts() {
|
||||
/* L'arc défini par trois points est issue d'une macro-construction.
|
||||
* Par nécessité, les extrémités de l'arc sont des points construits
|
||||
* qui "Sautent" en s'échangeant lorsque le cercle support change de
|
||||
* "courbure". La formule en x se trouvant par exemple dans le getStart
|
||||
* de l'arc est : if(a(C,A,B)<180,x(A),x(C))
|
||||
* Pour tester le produit vectoriel OA^OC, il faut récupérer les "vraies"
|
||||
* extrémités A et C, à savoir les points qui ont servi à créer l'arc.
|
||||
* Cela se fait par une regExp.
|
||||
*/
|
||||
if (hasRange()) {
|
||||
String st=getStart().getEX();
|
||||
String reg="\\Qif(a(\\E[^,]*,[^,]*,[^\\)]*\\Q)<180,x(\\E([^\\)]*)\\Q),x(\\E([^\\)]*)\\)\\)";
|
||||
Matcher m=Pattern.compile(reg).matcher(st);
|
||||
// if (m.find()) {
|
||||
// PointObject RealStartPt=(PointObject) Cn.find(m.group(1));
|
||||
// PointObject RealEndPt=(PointObject) Cn.find(m.group(2));
|
||||
// if (getStart().equals(RealStartPt)) {
|
||||
// RealCorrespondingStartPt=StartPt;
|
||||
// } else {
|
||||
// RealCorrespondingStartPt=EndPt;
|
||||
// }
|
||||
// isArc3pts=true;
|
||||
// System.out.println(RealCorrespondingStartPt.getName()+" "+getStart().getName());
|
||||
// }
|
||||
isArc3pts=m.find();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Pour les arcs de cercles, calcule l'angle A=SOE avec S=start et E=end
|
||||
public double computeSOE() {
|
||||
A1=Math.atan2(getStart().getY()-Y, getStart().getX()-X);
|
||||
if (A1<0) {
|
||||
A1+=2*Math.PI;
|
||||
}
|
||||
A2=Math.atan2(getEnd().getY()-Y, getEnd().getX()-X);
|
||||
if (A2<0) {
|
||||
A2+=2*Math.PI;
|
||||
}
|
||||
if (A2<A1) {
|
||||
A2+=2*Math.PI;
|
||||
}
|
||||
A=A2-A1;
|
||||
|
||||
|
||||
|
||||
if (!Obtuse&&A>Math.PI+1e-10) {
|
||||
A1=A2;
|
||||
if (A1>=2*Math.PI) {
|
||||
A1-=2*Math.PI;
|
||||
}
|
||||
A=2*Math.PI-A;
|
||||
A2=A1+A;
|
||||
|
||||
|
||||
}
|
||||
if (Partial) {
|
||||
A1-=10/180.0*Math.PI;
|
||||
A+=20/180.0*Math.PI;
|
||||
}
|
||||
return A;
|
||||
}
|
||||
|
||||
// Pour les arcs de cercles, calcule l'angle A=SOP avec S=start et P=le point passé en param
|
||||
public double computeSOP(PointObject P) {
|
||||
double AS=Math.atan2(getStart().getY()-Y, getStart().getX()-X);
|
||||
if (AS<0) {
|
||||
AS+=2*Math.PI;
|
||||
}
|
||||
double AP=Math.atan2(P.getY()-Y, P.getX()-X);
|
||||
if (AP<0) {
|
||||
AP+=2*Math.PI;
|
||||
}
|
||||
if (AP<AS) {
|
||||
AP+=2*Math.PI;
|
||||
}
|
||||
double AA=AP-AS;
|
||||
if (!Obtuse&&AA>Math.PI+1e-10) {
|
||||
AA=2*Math.PI-AA;
|
||||
}
|
||||
if (Partial) {
|
||||
AA+=20/180.0*Math.PI;
|
||||
}
|
||||
return AA;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test, if the projection of (x,y) to the arc contains that point.
|
||||
*/
|
||||
public boolean contains(final double x, final double y) {
|
||||
if (!hasRange()) {
|
||||
return true;
|
||||
}
|
||||
computeSOE();
|
||||
double a=Math.atan2(y-Y, x-X);
|
||||
if (a<0) {
|
||||
a+=2*Math.PI;
|
||||
}
|
||||
double d=a-A1;
|
||||
if (d<0) {
|
||||
d+=2*Math.PI;
|
||||
}
|
||||
return d<A+0.0001;
|
||||
}
|
||||
|
||||
public void project(final PointObject P) {
|
||||
|
||||
double dx=P.getX()-getX(), dy=P.getY()-getY();
|
||||
final double r=Math.sqrt(dx*dx+dy*dy);
|
||||
double X=0, Y=0;
|
||||
if (r<1e-10) {
|
||||
X=getX()+getR();
|
||||
Y=getY();
|
||||
} else {
|
||||
X=getX()+dx/r*getR();
|
||||
Y=getY()+dy/r*getR();
|
||||
}
|
||||
double Alpha=Math.atan2(P.getY()-getY(), P.getX()-getX());
|
||||
if (hasRange()&&getStart()!=P&&getEnd()!=P) {
|
||||
if (Alpha<0) {
|
||||
Alpha+=2*Math.PI;
|
||||
}
|
||||
computeSOE();
|
||||
final double a1=getA1(), a2=getA2();
|
||||
if (Alpha<a1) {
|
||||
Alpha+=2*Math.PI;
|
||||
}
|
||||
if (Alpha>a2) {
|
||||
if (2*Math.PI-(Alpha-a1)<Alpha-a2) {
|
||||
Alpha=a1;
|
||||
} else {
|
||||
Alpha=a2;
|
||||
}
|
||||
}
|
||||
X=getX()+getR()*Math.cos(Alpha);
|
||||
Y=getY()+getR()*Math.sin(Alpha);
|
||||
}
|
||||
P.setXY(X, Y);
|
||||
P.setA(Alpha);
|
||||
|
||||
if (hasRange()&&(StartPt!=P)&&(EndPt!=P)&&(P.isPointOn())) {
|
||||
double soe=computeSOE();
|
||||
double sop=computeSOP(P);
|
||||
if (soe!=0) {
|
||||
P.setAlpha(sop/soe);
|
||||
// if (isArc3pts&&!StartPt.equals(RealCorrespondingStartPt)) {
|
||||
// P.setAlpha(1-sop/soe);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistance(final PointObject P) {
|
||||
final double dx=P.getX()-getX(), dy=P.getY()-getY();
|
||||
final double r=Math.sqrt(dx*dx+dy*dy);
|
||||
double X=0, Y=0;
|
||||
if (r<1e-10) {
|
||||
X=getX()+getR();
|
||||
Y=getY();
|
||||
} else {
|
||||
X=getX()+dx/r*getR();
|
||||
Y=getY()+dy/r*getR();
|
||||
}
|
||||
double Alpha=Math.atan2(P.getY()-getY(), P.getX()-getX());
|
||||
if (hasRange()&&getStart()!=P&&getEnd()!=P) {
|
||||
if (Alpha<0) {
|
||||
Alpha+=2*Math.PI;
|
||||
}
|
||||
computeSOE();
|
||||
final double a1=getA1(), a2=getA2();
|
||||
if (Alpha<a1) {
|
||||
Alpha+=2*Math.PI;
|
||||
}
|
||||
if (Alpha>a2) {
|
||||
if (2*Math.PI-(Alpha-a1)<Alpha-a2) {
|
||||
Alpha=a1;
|
||||
} else {
|
||||
Alpha=a2;
|
||||
}
|
||||
}
|
||||
X=getX()+getR()*Math.cos(Alpha);
|
||||
Y=getY()+getR()*Math.sin(Alpha);
|
||||
}
|
||||
final double d=Math.sqrt((P.getX()-X)*(P.getX()-X)
|
||||
+(P.getY()-Y)*(P.getY()-Y));
|
||||
return (int) Math.round(d*Cn.getPixel());
|
||||
}
|
||||
|
||||
public double det(PointObject M, PointObject N) {
|
||||
double determinant=(M.getX()-X)*(N.getY()-Y)-(M.getY()-Y)*(N.getX()-X);
|
||||
return determinant;
|
||||
}
|
||||
|
||||
public void project(final PointObject P, final double alpha) {
|
||||
|
||||
if (hasRange()&&(StartPt!=P)&&(EndPt!=P)&&(P.isPointOn())) {
|
||||
detectArc3Pts();
|
||||
double soe=computeSOE();
|
||||
double k=P.getAlpha();
|
||||
// if (isArc3pts&&!StartPt.equals(RealCorrespondingStartPt)) {
|
||||
// k=1-k;
|
||||
// }
|
||||
double sop=soe*k;
|
||||
// Rotation du vecteur OS d'angle sop :
|
||||
PointObject start=getStart();
|
||||
double xx=(start.getX()-getX())*Math.cos(sop)-(start.getY()-getY())*Math.sin(sop);
|
||||
double yy=(start.getX()-getX())*Math.sin(sop)+(start.getY()-getY())*Math.cos(sop);
|
||||
double unit=getR()/(Math.sqrt((start.getX()-getX())*(start.getX()-getX())+(start.getY()-getY())*(start.getY()-getY())));
|
||||
double x0=getX()+xx*unit, y0=getY()+yy*unit;
|
||||
// if (isArc3pts&&!StartPt.equals(RealCorrespondingStartPt)) {
|
||||
//
|
||||
// }
|
||||
// Gestion de la continuité du déplacement d'un point sur objet sur un arc de cercle
|
||||
// Si les extrémités de l'arc s'échangent, il faut un coef. barycentrique égal à
|
||||
// 1-k :
|
||||
if (isArc3pts) {
|
||||
sop=soe*(1-k);
|
||||
xx=(start.getX()-getX())*Math.cos(sop)-(start.getY()-getY())*Math.sin(sop);
|
||||
yy=(start.getX()-getX())*Math.sin(sop)+(start.getY()-getY())*Math.cos(sop);
|
||||
unit=getR()/(Math.sqrt((start.getX()-getX())*(start.getX()-getX())+(start.getY()-getY())*(start.getY()-getY())));
|
||||
double x1=getX()+xx*unit, y1=getY()+yy*unit;
|
||||
double d0=(P.getX()-x0)*(P.getX()-x0)+(P.getY()-y0)*(P.getY()-y0);
|
||||
double d1=(P.getX()-x1)*(P.getX()-x1)+(P.getY()-y1)*(P.getY()-y1);
|
||||
if (d0>d1) {
|
||||
x0=x1;
|
||||
y0=y1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Coordonnées du point P :
|
||||
P.setXY(x0, y0);
|
||||
|
||||
if (!Obtuse) {
|
||||
// S'il s'agit d'un arc180, il faut que Start,P et End
|
||||
// soient sur l'arc dans le même ordre, on étudie donc
|
||||
// le produit des déterminants :
|
||||
if (det(getStart(), getEnd())*det(getStart(), P)<0) {
|
||||
k=-k;
|
||||
P.setAlpha(k);
|
||||
sop=soe*k;
|
||||
|
||||
// Rotation du vecteur OS d'angle sop :
|
||||
start=getStart();
|
||||
xx=(start.getX()-getX())*Math.cos(sop)-(start.getY()-getY())*Math.sin(sop);
|
||||
yy=(start.getX()-getX())*Math.sin(sop)+(start.getY()-getY())*Math.cos(sop);
|
||||
|
||||
// Coordonnées du point P :
|
||||
P.setXY(getX()+xx*unit, getY()+yy*unit);
|
||||
}
|
||||
}
|
||||
// System.out.println("**** detSOE="+det(getStart(), getEnd())+" : detSOP="+det(getStart(), P));
|
||||
// System.out.println("k="+k);
|
||||
|
||||
|
||||
} else {
|
||||
final double dx=P.getX()-getX(), dy=P.getY()-getY();
|
||||
final double r=Math.sqrt(dx*dx+dy*dy);
|
||||
double X=0, Y=0;
|
||||
if (r<1e-10) {
|
||||
X=getX()+getR();
|
||||
Y=getY();
|
||||
} else {
|
||||
X=getX()+dx/r*getR();
|
||||
Y=getY()+dy/r*getR();
|
||||
}
|
||||
if (hasRange()&&getStart()!=P&&getEnd()!=P) {
|
||||
double Alpha=P.getAlpha();
|
||||
if (Alpha<0) {
|
||||
Alpha+=2*Math.PI;
|
||||
}
|
||||
if (Alpha>=2*Math.PI) {
|
||||
Alpha-=2*Math.PI;
|
||||
}
|
||||
computeSOE();
|
||||
final double a1=getA1(), a2=getA2();
|
||||
if (Alpha<a1) {
|
||||
Alpha+=2*Math.PI;
|
||||
}
|
||||
if (Alpha>a2) {
|
||||
if (2*Math.PI-(Alpha-a1)<Alpha-a2) {
|
||||
Alpha=a1;
|
||||
} else {
|
||||
Alpha=a2;
|
||||
}
|
||||
}
|
||||
P.setA(Alpha);
|
||||
X=getX()+getR()*Math.cos(Alpha);
|
||||
Y=getY()+getR()*Math.sin(Alpha);
|
||||
} else {
|
||||
X=getX()+getR()*Math.cos(alpha);
|
||||
Y=getY()+getR()*Math.sin(alpha);
|
||||
}
|
||||
P.setXY(X, Y);
|
||||
}
|
||||
}
|
||||
|
||||
public double containsInside(final PointObject P) {
|
||||
final double dx=P.getX()-X, dy=P.getY()-Y;
|
||||
final double r=Math.sqrt(dx*dx+dy*dy);
|
||||
if (r<R*(1-1e-10)) {
|
||||
return 1;
|
||||
}
|
||||
if (r<R*(1+1e-10)) {
|
||||
return 0.5;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean keepInside(final PointObject P) {
|
||||
final double dx=P.getX()-X, dy=P.getY()-Y;
|
||||
final double r=Math.sqrt(dx*dx+dy*dy);
|
||||
double f=1;
|
||||
if (Filled&&ColorType==THIN) {
|
||||
f=0.9999;
|
||||
}
|
||||
if (r<R*f||R<1e-10) {
|
||||
return true;
|
||||
}
|
||||
P.setXY(X+dx/r*(R*f), Y+dy/r*(R*f));
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canInteresectWith(final ConstructionObject o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void repulse(final PointObject P) {
|
||||
project(P);
|
||||
}
|
||||
}
|
||||
467
rene/zirkel/objects/PrimitiveLineObject.java
Normal file
467
rene/zirkel/objects/PrimitiveLineObject.java
Normal file
|
|
@ -0,0 +1,467 @@
|
|||
/*
|
||||
|
||||
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: PrimitiveLineObject.java
|
||||
import java.awt.Checkbox;
|
||||
import java.awt.Color;
|
||||
import java.awt.Frame;
|
||||
import java.awt.TextField;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import eric.JEricPanel;
|
||||
|
||||
import rene.gui.Global;
|
||||
import rene.gui.IconBar;
|
||||
import rene.gui.MyLabel;
|
||||
import rene.gui.TextFieldAction;
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.gui.Global;
|
||||
import rene.zirkel.ZirkelCanvas;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.expression.ExpressionColor;
|
||||
import rene.zirkel.graphics.MyGraphics;
|
||||
import rene.zirkel.graphics.MainGraphics;
|
||||
import rene.zirkel.structures.Coordinates;
|
||||
|
||||
|
||||
|
||||
public class PrimitiveLineObject extends ConstructionObject implements
|
||||
PointonObject {
|
||||
|
||||
protected double X1, Y1, DX, DY;
|
||||
protected double DX3D=0;
|
||||
protected double DY3D=0;
|
||||
protected double DZ3D=0;
|
||||
protected PointObject P1;
|
||||
PointObject Dep[];
|
||||
int NDep;
|
||||
boolean Partial = false;
|
||||
|
||||
public PrimitiveLineObject(final Construction c) {
|
||||
super(c);
|
||||
setColor(ColorIndex, SpecialColor);
|
||||
}
|
||||
|
||||
public PrimitiveLineObject(final Construction c, final String Nme) {
|
||||
super(c, Nme);
|
||||
setColor(ColorIndex, SpecialColor);
|
||||
}
|
||||
|
||||
public void setP1DXDY(final PointObject p, final double dx, final double dy) {
|
||||
P1 = p;
|
||||
DX = dx;
|
||||
DY = dy;
|
||||
X1 = P1.getX();
|
||||
Y1 = P1.getY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaults() {
|
||||
setShowName(Global.getParameter("options.line.shownames", false));
|
||||
setShowValue(Global.getParameter("options.line.showvalues", false));
|
||||
setColor(Global.getParameter("options.line.color", 0), Global
|
||||
.getParameter("options.line.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.line.colortype", 0));
|
||||
setHidden(Cn.Hidden);
|
||||
setObtuse(Cn.Obtuse);
|
||||
setSolid(Cn.Solid);
|
||||
setLarge(Global.getParameter("options.line.large", false));
|
||||
setBold(Global.getParameter("options.line.bold", false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetDefaults() {
|
||||
setShowName(Global.getParameter("options.line.shownames", false));
|
||||
setShowValue(Global.getParameter("options.line.showvalues", false));
|
||||
setColor(Global.getParameter("options.line.color", 0), Global
|
||||
.getParameter("options.line.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.line.colortype", 0));
|
||||
setLarge(Global.getParameter("options.line.large", false));
|
||||
setBold(Global.getParameter("options.line.bold", false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Line";
|
||||
}
|
||||
|
||||
double k1, k2;
|
||||
boolean k12valid = false;
|
||||
|
||||
@Override
|
||||
public void paint(final MyGraphics g, final ZirkelCanvas zc) {
|
||||
if (!Valid || mustHide(zc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// compute middle of the screen:
|
||||
final double xm = (zc.minX() + zc.maxX()) / 2, ym = (zc.minY() + zc
|
||||
.maxY()) / 2;
|
||||
// compute distance from middle to line:
|
||||
final double d = (xm - X1) * DY - (ym - Y1) * DX;
|
||||
// compute point with minimal distance
|
||||
final double x = xm - d * DY, y = ym + d * DX;
|
||||
// compute size of the screen
|
||||
final double a = Math.max(zc.maxX() - zc.minX(), zc.maxY() - zc.minY());
|
||||
if (Math.abs(d) > a) {
|
||||
return;
|
||||
}
|
||||
// compute distance from closest point to source
|
||||
final double b = (x - X1) * DX + (y - Y1) * DY;
|
||||
// compute the two visible endpoints
|
||||
k1 = b - a;
|
||||
k2 = b + a;
|
||||
k12valid = true;
|
||||
if (Partial && Dep != null && !zc.showHidden()) {
|
||||
final double dd = (zc.maxX() - zc.minX()) / 20;
|
||||
double dmin = -dd, dmax = +dd;
|
||||
if (Dep != null) {
|
||||
for (int i = 0; i < NDep; i++) {
|
||||
if (!Dep[i].valid() || Dep[i].mustHide(zc)) {
|
||||
continue;
|
||||
}
|
||||
final double s = project(Dep[i].getX(), Dep[i].getY());
|
||||
if (s - dd < dmin) {
|
||||
dmin = s - dd;
|
||||
} else if (s + dd > dmax) {
|
||||
dmax = s + dd;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (k1 < dmin) {
|
||||
k1 = dmin;
|
||||
}
|
||||
if (k2 > dmax) {
|
||||
k2 = dmax;
|
||||
}
|
||||
}
|
||||
final double c1 = zc.col(X1 + k1 * DX), c2 = zc.col(X1 + k2 * DX), r1 = zc
|
||||
.row(Y1 + k1 * DY), r2 = zc.row(Y1 + k2 * DY);
|
||||
// paint:
|
||||
if (isStrongSelected() && g instanceof MainGraphics) {
|
||||
((MainGraphics) g).drawMarkerLine(c1, r1, c2, r2);
|
||||
}
|
||||
|
||||
g.setColor(this);
|
||||
|
||||
if (tracked())
|
||||
zc.UniversalTrack.drawTrackLine(this, c1, r1, c2, r2);
|
||||
|
||||
g.drawLine(c1, r1, c2, r2, this);
|
||||
final String s = getDisplayText();
|
||||
if (!s.equals("")) {
|
||||
g.setLabelColor(this);
|
||||
setFont(g);
|
||||
DisplaysText = true;
|
||||
if (KeepClose) {
|
||||
final double side = (YcOffset < 0) ? 1 : -1;
|
||||
drawLabel(g, s, zc, X1 + XcOffset * DX, Y1 + XcOffset * DY,
|
||||
side * DX, side * DY, 0, 0);
|
||||
} else {
|
||||
drawLabel(g, s, zc, x + a / 5 * DX, y + a / 5 * DY, DX, DY,
|
||||
XcOffset, YcOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canKeepClose() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setKeepClose(final double x, final double y) {
|
||||
KeepClose = true;
|
||||
XcOffset = (x - X1) * DX + (y - Y1) * DY;
|
||||
YcOffset = (x - X1) * DY - (y - Y1) * DX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int c, final int r, final ZirkelCanvas zc) {
|
||||
if (!displays(zc)) {
|
||||
return false;
|
||||
}
|
||||
// compute point at c,r
|
||||
final double x = zc.x(c), y = zc.y(r);
|
||||
// compute distance from x,y
|
||||
final double d = (x - X1) * DY - (y - Y1) * DX;
|
||||
// scale in screen coordinates
|
||||
Value = Math.abs(zc.col(zc.minX() + d) - zc.col(zc.minX()));
|
||||
return Value < zc.selectionSize() * 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onlynearto(final int c, final int r, final ZirkelCanvas zc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Coordinates intersect(final PrimitiveLineObject l1,
|
||||
final PrimitiveLineObject l2) // compute the intersection
|
||||
// coordinates of two lines
|
||||
{
|
||||
final double det = -l1.DX * l2.DY + l1.DY * l2.DX;
|
||||
if (Math.abs(det) < 1e-10) {
|
||||
return null;
|
||||
}
|
||||
final double a = (-(l2.X1 - l1.X1) * l2.DY + (l2.Y1 - l1.Y1) * l2.DX)
|
||||
/ det;
|
||||
return new Coordinates(l1.X1 + a * l1.DX, l1.Y1 + a * l1.DY);
|
||||
}
|
||||
|
||||
public static Coordinates intersect(final PrimitiveLineObject l,
|
||||
final PrimitiveCircleObject c) // compute the intersection
|
||||
// coordinates of a line with a
|
||||
// circle
|
||||
{
|
||||
double x = c.getX(), y = c.getY();
|
||||
final double r = c.getR();
|
||||
final double d = (x - l.X1) * l.DY - (y - l.Y1) * l.DX;
|
||||
if (Math.abs(d) > r + 1e-10) {
|
||||
return null;
|
||||
}
|
||||
x -= d * l.DY;
|
||||
y += d * l.DX;
|
||||
double h = r * r - d * d;
|
||||
if (h > 0) {
|
||||
h = Math.sqrt(h);
|
||||
} else {
|
||||
h = 0;
|
||||
}
|
||||
return new Coordinates(x + h * l.DX, y + h * l.DY, x - h * l.DX, y - h
|
||||
* l.DY);
|
||||
}
|
||||
|
||||
public static Coordinates intersect(final PrimitiveLineObject l,
|
||||
final QuadricObject q) {
|
||||
// compute the intersection coordinates of a line with a quadric
|
||||
// done with XCAS :
|
||||
// System.out.println("l.DX="+l.DX+" l.DY="+l.DY);
|
||||
final double M = -l.DY, N2 = l.DX, P = -(M * l.X1 + N2 * l.Y1);
|
||||
// System.out.println("M="+M+" N2="+N2+" P="+P);
|
||||
final double A = q.X[0], B = q.X[1], C = q.X[2], D = q.X[3], E = q.X[4], F = q.X[5];
|
||||
double x1 = 0, x2 = 0, y1 = 0, y2 = 0;
|
||||
if (N2 != 0) {
|
||||
final double part1 = -2 * B * M * P - C * N2 * N2 + D * M * N2 + E
|
||||
* N2 * P;
|
||||
final double part2 = Math.abs(N2)
|
||||
* Math.sqrt(-2 * M * D * N2 * C + 4 * P * D * A * N2 + 4
|
||||
* P * M * B * C + 4 * E * M * N2 * F - 2 * E * P
|
||||
* N2 * C - 2 * E * P * M * D - 4 * M * M * B * F
|
||||
- 4 * P * P * A * B - 4 * A * N2 * N2 * F + N2 * N2
|
||||
* C * C + M * M * D * D + E * E * P * P);
|
||||
|
||||
final double part3 = 2 * A * N2 * N2 + 2 * B * M * M + (-2 * E) * M
|
||||
* N2;
|
||||
x1 = (part1 + part2) / part3;
|
||||
if (Double.isNaN(x1)) {
|
||||
return null;
|
||||
}
|
||||
y1 = (-M * x1 - P) / N2;
|
||||
x2 = (part1 - part2) / part3;
|
||||
y2 = (-M * x2 - P) / N2;
|
||||
if (((x2 - x1) / l.DX) < 0) {
|
||||
return new Coordinates(x2, y2, x1, y1);
|
||||
}
|
||||
} else {
|
||||
x1 = -P / M;
|
||||
x2 = x1;
|
||||
final double part1 = -D * M * M + E * M * P;
|
||||
final double part2 = Math.abs(M)
|
||||
* Math.sqrt(4 * P * M * B * C - 2 * E * P * M * D - 4 * M
|
||||
* M * B * F - 4 * P * P * A * B + M * M * D * D + E
|
||||
* E * P * P);
|
||||
final double part3 = 2 * M * M * B;
|
||||
y1 = (part1 + part2) / part3;
|
||||
if (Double.isNaN(y1)) {
|
||||
return null;
|
||||
}
|
||||
y2 = (part1 - part2) / part3;
|
||||
if (((y2 - y1) / l.DY) < 0) {
|
||||
return new Coordinates(x2, y2, x1, y1);
|
||||
}
|
||||
}
|
||||
|
||||
return new Coordinates(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
public double getDX() {
|
||||
return DX;
|
||||
}
|
||||
|
||||
public double getDY() {
|
||||
return DY;
|
||||
}
|
||||
|
||||
public double getDX3D() {
|
||||
return DX3D;
|
||||
}
|
||||
|
||||
public double getDY3D() {
|
||||
return DY3D;
|
||||
}
|
||||
|
||||
public double getDZ3D() {
|
||||
return DZ3D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getX() {
|
||||
return X1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getY() {
|
||||
return Y1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getEquation() {
|
||||
double y = DX, x = -DY;
|
||||
double c = y * Y1 + x * X1;
|
||||
if (c < 0) {
|
||||
c = -c;
|
||||
x = -x;
|
||||
y = -y;
|
||||
}
|
||||
if (Math.abs(x) < 1e-10 && y < 0) {
|
||||
c = -c;
|
||||
x = -x;
|
||||
y = -y;
|
||||
} else if (Math.abs(y) < 1e-10 && x < 0) {
|
||||
c = -c;
|
||||
x = -x;
|
||||
y = -y;
|
||||
}
|
||||
final String s = helpDisplayValue(true, x, "x");
|
||||
return s + helpDisplayValue(s.equals(""), y, "y") + "="
|
||||
+ ((Math.abs(c) < 1e-10) ? "0" : helpDisplayNumber(true, c));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test, if the projection of (x,y) to the line contains that point.
|
||||
*/
|
||||
public boolean contains(final double x, final double y) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
if (Partial) {
|
||||
xml.printArg("partial", "true");
|
||||
}
|
||||
}
|
||||
|
||||
public double project(final double x, final double y) {
|
||||
return (x - X1) * DX + (y - Y1) * DY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final ConstructionObject o) {
|
||||
if (!(o instanceof PrimitiveLineObject) || !o.valid()) {
|
||||
return false;
|
||||
}
|
||||
final PrimitiveLineObject l = (PrimitiveLineObject) o;
|
||||
return equals(DX * l.DY - DY * l.DX, 0)
|
||||
&& equals((X1 - l.X1) * DY - (Y1 - l.Y1) * DX, 0);
|
||||
}
|
||||
|
||||
public PointObject getP1() {
|
||||
return P1;
|
||||
}
|
||||
|
||||
public Enumeration points() {
|
||||
return depending();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean locallyLike(final ConstructionObject o) {
|
||||
if (!(o instanceof PrimitiveLineObject)) {
|
||||
return false;
|
||||
}
|
||||
return (equals(DX, ((PrimitiveLineObject) o).DX) && equals(DY,
|
||||
((PrimitiveLineObject) o).DY))
|
||||
|| (equals(-DX, ((PrimitiveLineObject) o).DX) && equals(-DY,
|
||||
((PrimitiveLineObject) o).DY));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPartial() {
|
||||
return Partial;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPartial(final boolean partial) {
|
||||
if (Partial == partial) {
|
||||
return;
|
||||
}
|
||||
Partial = partial;
|
||||
if (partial) {
|
||||
Dep = new PointObject[16];
|
||||
NDep = 0;
|
||||
} else {
|
||||
Dep = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void addDep(final PointObject p) {
|
||||
if (!Partial || Dep == null || NDep >= Dep.length) {
|
||||
return;
|
||||
}
|
||||
Dep[NDep++] = p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCircleDep() {
|
||||
NDep = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistance(final PointObject P) {
|
||||
final double h = project(P.getX(), P.getY());
|
||||
final double dx = P.getX() - (getX() + h * getDX());
|
||||
final double dy = P.getY() - (getY() + h * getDY());
|
||||
final double d = Math.sqrt(dx * dx + dy * dy);
|
||||
return (int) Math.round(d * Cn.getPixel());
|
||||
}
|
||||
|
||||
public void project(final PointObject P) {
|
||||
final double h = project(P.getX(), P.getY());
|
||||
P.setXY(getX() + h * getDX(), getY() + h * getDY());
|
||||
P.setA(h);
|
||||
}
|
||||
|
||||
public void project(final PointObject P, final double alpha) {
|
||||
P.setXY(getX() + alpha * getDX(), getY() + alpha * getDY());
|
||||
}
|
||||
|
||||
public boolean canInteresectWith(final ConstructionObject o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void repulse(final PointObject P) {
|
||||
project(P);
|
||||
}
|
||||
}
|
||||
829
rene/zirkel/objects/QuadricObject.java
Normal file
829
rene/zirkel/objects/QuadricObject.java
Normal file
|
|
@ -0,0 +1,829 @@
|
|||
/*
|
||||
|
||||
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: QuadricObject.java
|
||||
import java.util.ArrayList;
|
||||
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.ExpressionColor;
|
||||
import rene.zirkel.expression.Quartic;
|
||||
import rene.zirkel.graphics.MyGraphics;
|
||||
import rene.zirkel.graphics.PolygonDrawer;
|
||||
import rene.zirkel.structures.Complex;
|
||||
import rene.zirkel.structures.CoordinatesXY;
|
||||
|
||||
public class QuadricObject extends ConstructionObject implements PointonObject,
|
||||
MoveableObject {
|
||||
|
||||
public PointObject P[];
|
||||
static Count N=new Count();
|
||||
public double X[];
|
||||
|
||||
public QuadricObject(final Construction c, final PointObject p[]) {
|
||||
super(c);
|
||||
P=p;
|
||||
validate();
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaults() {
|
||||
setShowName(Global.getParameter("options.quadric.shownames", false));
|
||||
setShowValue(Global.getParameter("options.quadric.showvalues", false));
|
||||
setColor(Global.getParameter("options.quadric.color", 0), Global.getParameter("options.circle.pcolor", (ExpressionColor) null, this));
|
||||
|
||||
setColorType(Global.getParameter("options.quadric.colortype", 0));
|
||||
setHidden(Cn.Hidden);
|
||||
//setObtuse(Cn.Obtuse);
|
||||
//setSolid(Cn.Solid);
|
||||
setLarge(Cn.LargeFont);
|
||||
setBold(Cn.BoldFont);
|
||||
//setPartial(Cn.Partial);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetDefaults() {
|
||||
setShowName(Global.getParameter("options.quadric.shownames", false));
|
||||
setShowValue(Global.getParameter("options.quadric.showvalues", false));
|
||||
setColor(Global.getParameter("options.quadric.color", 0), Global.getParameter("options.circle.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.quadric.colortype", 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Quadric";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getN() {
|
||||
return N.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
try {
|
||||
final String Names[]=new String[P.length];
|
||||
for (int i=0; i<P.length; i++) {
|
||||
Names[i]=P[i].getName();
|
||||
}
|
||||
if (P[0].is3D()&&P[1].is3D()&&P[2].is3D()&&P[3].is3D()&&P[4].is3D()) setText(Global.name("text.circle3D"));
|
||||
else setText(textAny(Global.name("text.quadric"), Names));
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
}
|
||||
private static final double cub2=Math.pow(2, 1.0/3.0);
|
||||
|
||||
public static ArrayList<CoordinatesXY> intersect(final QuadricObject quad1,
|
||||
final QuadricObject quad2) {
|
||||
ArrayList<CoordinatesXY> points=new ArrayList<CoordinatesXY>();
|
||||
|
||||
// coeffs de x^2, xy, y^2, x, y et Cte :
|
||||
double a=quad1.X[0], b=quad1.X[4], c=quad1.X[1], d=quad1.X[2], e=quad1.X[3], f=quad1.X[5];
|
||||
double aa=quad2.X[0], bb=quad2.X[4], cc=quad2.X[1], dd=quad2.X[2], ee=quad2.X[3], ff=quad2.X[5];
|
||||
|
||||
// System.out.println("*************");
|
||||
// System.out.println("a="+a);
|
||||
// System.out.println("b="+b);
|
||||
// System.out.println("c="+c);
|
||||
// System.out.println("d="+d);
|
||||
// System.out.println("e="+e);
|
||||
// System.out.println("f="+f);
|
||||
// System.out.println("aa="+aa);
|
||||
// System.out.println("bb="+bb);
|
||||
// System.out.println("cc="+cc);
|
||||
// System.out.println("dd="+dd);
|
||||
// System.out.println("ee="+ee);
|
||||
// System.out.println("ff="+ff);
|
||||
|
||||
|
||||
double k1=-aa*b*bb*c+a*bb*bb*c+aa*aa*c*c+aa*b*b*cc-a*b*bb*cc-2*a*aa*c*cc+a*a*cc*cc;
|
||||
double k2=bb*bb*c*d-b*bb*cc*d-2*aa*c*cc*d+2*a*cc*cc*d-b*bb*c*dd+2*aa*c*c*dd+b*b*cc*dd-2*a*c*cc*dd-aa*bb*c*e+2*aa*b*cc*e-a*bb*cc*e-aa*b*c*ee+2*a*bb*c*ee-a*b*cc*ee;
|
||||
double k3=cc*cc*d*d-2*c*cc*d*dd+c*c*dd*dd-bb*cc*d*e-bb*c*dd*e+2*b*cc*dd*e+aa*cc*e*e+2*bb*c*d*ee-b*cc*d*ee-b*c*dd*ee-aa*c*e*ee-a*cc*e*ee+a*c*ee*ee+bb*bb*c*f-b*bb*cc*f-2*aa*c*cc*f+2*a*cc*cc*f-b*bb*c*ff+2*aa*c*c*ff+b*b*cc*ff-2*a*c*cc*ff;
|
||||
double k4=cc*dd*e*e-cc*d*e*ee-c*dd*e*ee+c*d*ee*ee+2*cc*cc*d*f-2*c*cc*dd*f-bb*cc*e*f+2*bb*c*ee*f-b*cc*ee*f-2*c*cc*d*ff+2*c*c*dd*ff-bb*c*e*ff+2*b*cc*e*ff-b*c*ee*ff;
|
||||
double k5=-cc*e*ee*f+c*ee*ee*f+cc*cc*f*f+cc*e*e*ff-c*e*ee*ff-2*c*cc*f*ff+c*c*ff*ff;
|
||||
|
||||
|
||||
double u1=k2/(4*k1);
|
||||
double u2=k2*k2/(4*k1*k1)-2*k3/(3*k1);
|
||||
double u3=k2*k2/(2*k1*k1)-4*k3/(3*k1);
|
||||
double u4=-k2*k2*k2/(k1*k1*k1)+4*k2*k3/(k1*k1)-8*k4/k1;
|
||||
|
||||
|
||||
|
||||
double p1=k3*k3-3*k2*k4+12*k1*k5;
|
||||
double p2=2*k3*k3*k3-9*k2*k3*k4+27*k1*k4*k4+27*k2*k2*k5-72*k1*k3*k5;
|
||||
|
||||
// System.out.println("*************");
|
||||
// System.out.println("k1="+k1);
|
||||
// System.out.println("k2="+k2);
|
||||
// System.out.println("k3="+k3);
|
||||
// System.out.println("k4="+k4);
|
||||
// System.out.println("k5="+k5);
|
||||
|
||||
Complex q1=new Complex(-4*p1*p1*p1+p2*p2).sqrt();
|
||||
q1=Complex.plus(q1, new Complex(p2, 0));
|
||||
q1=q1.sqrt3();
|
||||
|
||||
// System.out.println("q1="+q1.real()+" + "+q1.img()+" I");
|
||||
|
||||
Complex r1=Complex.div(new Complex(cub2*p1), Complex.mult(new Complex(3*k1), q1));
|
||||
r1=Complex.plus(r1, Complex.div(q1, new Complex(3*cub2*k1)));
|
||||
|
||||
Complex sa=Complex.plus(new Complex(u2), r1);
|
||||
sa=Complex.div(sa.sqrt(), 2);
|
||||
|
||||
|
||||
Complex sb=Complex.minus(new Complex(u3), r1);
|
||||
sb=Complex.minus(sb, Complex.div(new Complex(u4), Complex.mult(8, sa)));
|
||||
sb=Complex.div(sb.sqrt(), 2);
|
||||
|
||||
Complex sc=Complex.minus(new Complex(u3), r1);
|
||||
sc=Complex.plus(sc, Complex.div(new Complex(u4), Complex.mult(8, sa)));
|
||||
sc=Complex.div(sc.sqrt(), 2);
|
||||
|
||||
Complex[] X=new Complex[4];
|
||||
Complex cu1=new Complex(-u1);
|
||||
|
||||
X[0]=Complex.minus(cu1, sa);
|
||||
X[0]=Complex.minus(X[0], sb);
|
||||
|
||||
X[1]=Complex.minus(cu1, sa);
|
||||
X[1]=Complex.plus(X[1], sb);
|
||||
|
||||
X[2]=Complex.plus(cu1, sa);
|
||||
X[2]=Complex.minus(X[2], sc);
|
||||
|
||||
X[3]=Complex.plus(cu1, sa);
|
||||
X[3]=Complex.plus(X[3], sc);
|
||||
|
||||
// System.out.println("*************");
|
||||
// System.out.println("x1 = "+X[0].real()+" + "+X[0].img()+" I");
|
||||
// System.out.println("x2 = "+X[1].real()+" + "+X[1].img()+" I");
|
||||
// System.out.println("x3 = "+X[2].real()+" + "+X[2].img()+" I");
|
||||
// System.out.println("x4 = "+X[3].real()+" + "+X[3].img()+" I");
|
||||
|
||||
// Recherche des ordonnées des points d'intersection :
|
||||
|
||||
double A=c, B, C, AA=cc, BB, CC;
|
||||
for (int i=0; i<4; i++) {
|
||||
if (Math.abs(X[i].img())>1E-10) {
|
||||
points.add(new CoordinatesXY());
|
||||
} else {
|
||||
B=b*X[i].real()+e;
|
||||
C=a*X[i].real()*X[i].real()+d*X[i].real()+f;
|
||||
BB=bb*X[i].real()+ee;
|
||||
CC=aa*X[i].real()*X[i].real()+dd*X[i].real()+ff;
|
||||
|
||||
double denom=A*BB-B*AA;
|
||||
if (Math.abs(denom)<1E-20) {
|
||||
points.add(new CoordinatesXY());
|
||||
} else {
|
||||
double y=(C*AA-A*CC)/denom;//formula by Dominique Tournès
|
||||
points.add(new CoordinatesXY(X[i].real(), y));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// System.out.println("*************");
|
||||
// System.out.println("x["+i+"]="+X[i].real());
|
||||
// System.out.println("y["+i+"]="+y);
|
||||
// System.out.println("A*BB-B*AA="+(A*BB-B*AA));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// System.out.println("*************");
|
||||
// for (int i=0;i<points.size();i++){
|
||||
// CoordinatesXY coords=points.get(i);
|
||||
// System.out.println("point "+i+" : "+coords.X+" "+coords.Y);
|
||||
// }
|
||||
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
for (int i=0; i<P.length; i++) {
|
||||
if (!P[i].valid()) {
|
||||
Valid=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Valid=true;
|
||||
|
||||
// Baue Koeffizientenmatrix auf (x^2,y^2,x,y,xy,1):
|
||||
final double A[][]=new double[5][6];
|
||||
for (int i=0; i<5; i++) {
|
||||
final double x=P[i].getX(), y=P[i].getY();
|
||||
A[i][0]=x*x;
|
||||
A[i][1]=y*y;
|
||||
A[i][2]=x;
|
||||
A[i][3]=y;
|
||||
A[i][4]=x*y;
|
||||
A[i][5]=1;
|
||||
double sum=0;
|
||||
for (int j=0; j<6; j++) {
|
||||
sum+=A[i][j]*A[i][j];
|
||||
}
|
||||
sum=Math.sqrt(sum);
|
||||
for (int j=0; j<6; j++) {
|
||||
A[i][j]/=sum;
|
||||
}
|
||||
}
|
||||
|
||||
// Gauflverfahren, um auf untere Dreiecksmatrix zu kommen
|
||||
int r=0;
|
||||
final int colindex[]=new int[6]; // Index der Stufe oder -1 (keine
|
||||
// Stufe)
|
||||
// Iteration ¸ber alle Spalten:
|
||||
for (int c=0; c<6; c++) {
|
||||
if (r>=5) // Schema schon fertig
|
||||
{
|
||||
colindex[c]=-1;
|
||||
continue;
|
||||
}
|
||||
// Berechne Pivotelement mit spaltenweiser Maximumssuche
|
||||
double max=Math.abs(A[r][c]);
|
||||
int imax=r;
|
||||
for (int i=r+1; i<5; i++) {
|
||||
final double h=Math.abs(A[i][c]);
|
||||
if (h>max) {
|
||||
max=h;
|
||||
imax=i;
|
||||
}
|
||||
}
|
||||
if (max>1e-13) { // Vertausche Zeilen:
|
||||
if (imax!=r) {
|
||||
final double h[]=A[imax];
|
||||
A[imax]=A[r];
|
||||
A[r]=h;
|
||||
}
|
||||
// Mache restliche Spalte zu 0:
|
||||
for (int i=r+1; i<5; i++) {
|
||||
final double lambda=A[i][c]/A[r][c];
|
||||
for (int j=c+1; j<6; j++) {
|
||||
A[i][j]-=lambda*A[r][j];
|
||||
}
|
||||
}
|
||||
colindex[c]=r;
|
||||
r++;
|
||||
} else {
|
||||
colindex[c]=-1;
|
||||
}
|
||||
}
|
||||
// Berechne die x-Werte:
|
||||
X=new double[6];
|
||||
for (int j=5; j>=0; j--) {
|
||||
if (colindex[j]<0) {
|
||||
X[j]=1;
|
||||
} else {
|
||||
double h=0;
|
||||
final int i=colindex[j];
|
||||
for (int k=j+1; k<6; k++) {
|
||||
h+=A[i][k]*X[k];
|
||||
}
|
||||
X[j]=-h/A[i][j];
|
||||
}
|
||||
}
|
||||
// Normalisiere
|
||||
double sum=0;
|
||||
for (int i=0; i<=5; i++) {
|
||||
sum+=Math.abs(X[i]);
|
||||
}
|
||||
if (sum<1e-10) {
|
||||
Valid=false;
|
||||
}
|
||||
for (int i=0; i<=5; i++) {
|
||||
X[i]/=sum;
|
||||
// Ce qui suit ressemble à un gag, pourtant il semble que l'epsilon au lieu de 0 en coeffs permet
|
||||
// de surmonter les effets de bord dans des cas particuliers (ex. hyperbole equilatère/parabole)
|
||||
// sans pour autant porter atteinte à la précision des coordonnées des points d'intersections
|
||||
// qui restent fiables à 1e-12, soit la précision maximale affichée du logiciel :
|
||||
X[i]=n(X[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static double n(double x) {
|
||||
if (Math.abs(x)<1E-16) {
|
||||
double sign=(Math.signum(x)<0)?-1:1;
|
||||
return 1.0E-16*sign;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(final MyGraphics g, final ZirkelCanvas zc) {
|
||||
if (!Valid||mustHide(zc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
g.setColor(this);
|
||||
// Draw the lower part of the quadrik (minus the root):
|
||||
final double start=zc.minX();
|
||||
double x=start;
|
||||
final double end=zc.maxX();
|
||||
final double h=zc.dx(zc.getOne());
|
||||
boolean valid=false, ptext=false;
|
||||
double c0=0, r0=0;
|
||||
double ctext=20, rtext=20;
|
||||
|
||||
final PolygonDrawer pd=new PolygonDrawer(true,g, this);
|
||||
|
||||
// Draw the lower part of the quadric (plus the root):
|
||||
while (x<=end) {
|
||||
try {
|
||||
final double y=computeLower(x);
|
||||
final double c=zc.col(x), r=zc.row(y);
|
||||
if (valid) {//en ajoutant r>0, la ligne verticale disparaissait; elle est réapparue!
|
||||
pd.drawTo(c, r);
|
||||
if (!ptext&&r0-r>c-c0&&zc.isInside(x, y)) {
|
||||
ctext=c;
|
||||
rtext=r;
|
||||
ptext=true;
|
||||
}
|
||||
} else {
|
||||
|
||||
pd.startPolygon(c, r);
|
||||
}
|
||||
c0=c;
|
||||
r0=r;
|
||||
valid=true;
|
||||
} catch (final RuntimeException e) {
|
||||
|
||||
valid=false;
|
||||
}
|
||||
x+=h;
|
||||
}
|
||||
pd.finishPolygon();
|
||||
// Draw the upper part of the quadric (plus the root):
|
||||
x=start-2*h;
|
||||
valid=false;
|
||||
while (x<=end+2*h) {
|
||||
try {
|
||||
|
||||
final double y=computeUpper(x);
|
||||
final double c=zc.col(x), r=zc.row(y);
|
||||
|
||||
if (valid) {
|
||||
pd.drawTo(c, r);
|
||||
// Try to find a position for the label:
|
||||
if (!ptext&&r0-r>c-c0&&zc.isInside(x, y)) {
|
||||
ctext=c;
|
||||
rtext=r;
|
||||
ptext=true;
|
||||
}
|
||||
} else // left edge of quadric, connect with lower part
|
||||
{
|
||||
try {
|
||||
final double y1=computeLower(x);
|
||||
if (x>=start-h&&x<=end+h) {
|
||||
g.drawLine(c, zc.row(y1), c, r, this);
|
||||
}
|
||||
} catch (final RuntimeException e) {
|
||||
}
|
||||
pd.startPolygon(c, r);
|
||||
}
|
||||
c0=c;
|
||||
r0=r;
|
||||
valid=true;
|
||||
} catch (final RuntimeException e) // no points in that range
|
||||
{
|
||||
if (valid) // we just left the right edge of the quadric
|
||||
{
|
||||
try {
|
||||
final double y1=computeLower(x-h);
|
||||
if (x-h>=start-h&&x-h<=end+h) {
|
||||
g.drawLine(c0, zc.row(y1), c0, r0, this);
|
||||
}
|
||||
} catch (final RuntimeException ex) {
|
||||
}
|
||||
}
|
||||
valid=false;
|
||||
}
|
||||
x+=h;
|
||||
}
|
||||
pd.finishPolygon();
|
||||
final String s=getDisplayText();
|
||||
if (!s.equals("")) {
|
||||
g.setLabelColor(this);
|
||||
setFont(g);
|
||||
DisplaysText=true;
|
||||
TX1=ctext+zc.col(XcOffset)-zc.col(0);
|
||||
TY1=rtext+zc.row(YcOffset)-zc.row(0);
|
||||
drawLabel(g, s);
|
||||
}
|
||||
}
|
||||
static public final String Tags[]={"x^2", "y^2", "x", "y", "xy"};
|
||||
|
||||
// public String getDisplayValue() {
|
||||
// String s="";
|
||||
// for (int i=0; i<5; i++) {
|
||||
// s=s+helpDisplayValue(i==0, -X[i], Tags[i]);
|
||||
// }
|
||||
// return s+"="+roundDisplay(X[5]);
|
||||
// }
|
||||
@Override
|
||||
public String getDisplayValue() {
|
||||
String s="";
|
||||
s+="("+Global.getLocaleNumber(-X[0], "length");
|
||||
s+="*";
|
||||
s+=Tags[0]+")";
|
||||
for (int i=1; i<5; i++) {
|
||||
s+="+";
|
||||
s+="("+Global.getLocaleNumber(-X[i], "length");
|
||||
s+="*";
|
||||
s+=Tags[i]+")";
|
||||
|
||||
// s=s+helpDisplayValue(i==0, -X[i], Tags[i]);
|
||||
}
|
||||
return s+"="+Global.getLocaleNumber(X[5], "length");
|
||||
// return s+"="+roundDisplay(X[5]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEquation() {
|
||||
return getDisplayValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int cc, final int rr, final ZirkelCanvas zc) {
|
||||
if (!displays(zc)) {
|
||||
return false;
|
||||
}
|
||||
final int size=(int) zc.selectionSize();
|
||||
final double start=zc.minX();
|
||||
double x=start;
|
||||
final double end=zc.maxX();
|
||||
final double h=zc.dx(zc.getOne());
|
||||
while (x<=end) {
|
||||
try {
|
||||
final double y=computeUpper(x);
|
||||
final double c=zc.col(x), r=zc.row(y);
|
||||
if (Math.abs(cc-c)<=size*3/2
|
||||
&&Math.abs(rr-r)<=size*3/2) {
|
||||
return true;
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
try {
|
||||
final double y=computeLower(x);
|
||||
final double c=zc.col(x), r=zc.row(y);
|
||||
if (Math.abs(cc-c)<=size*3/2
|
||||
&&Math.abs(rr-r)<=size*3/2) {
|
||||
return true;
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
x+=h;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public double computeUpper(final double x) {
|
||||
if (Math.abs(X[1])>1e-13) {
|
||||
final double p=(X[3]+x*X[4])/X[1], q=(X[0]*x*x+X[2]
|
||||
*x+X[5])
|
||||
/X[1];
|
||||
final double h=p*p/4-q;
|
||||
if (h<0) {
|
||||
throw new RuntimeException("");
|
||||
}
|
||||
return -p/2+Math.sqrt(h);
|
||||
} else {
|
||||
return -(X[0]*x*x+X[2]*x+X[5])/(X[3]+X[4]*x);
|
||||
}
|
||||
}
|
||||
|
||||
public double computeLower(final double x) {
|
||||
if (Math.abs(X[1])>1e-13) {
|
||||
final double p=(X[3]+x*X[4])/X[1], q=(X[0]*x*x+X[2]
|
||||
*x+X[5])
|
||||
/X[1];
|
||||
final double h=p*p/4-q;
|
||||
if (h<0) {
|
||||
throw new RuntimeException("");
|
||||
}
|
||||
return -p/2-Math.sqrt(h);
|
||||
} else {
|
||||
throw new RuntimeException("");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
for (int i=0; i<P.length; i++) {
|
||||
xml.printArg("point"+(i+1), P[i].getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration secondaryParams() {
|
||||
DL.reset();
|
||||
for (final PointObject element : P) {
|
||||
DL.add(element);
|
||||
}
|
||||
return DL.elements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
DL.reset();
|
||||
for (final PointObject element : P) {
|
||||
// System.out.println(element.getName());
|
||||
DL.add(element);
|
||||
}
|
||||
return DL.elements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
for (int i=0; i<P.length; i++) {
|
||||
P[i]=(PointObject) P[i].getTranslation();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructionObject copy(final double x, final double y) {
|
||||
try {
|
||||
final QuadricObject o=(QuadricObject) clone();
|
||||
setTranslation(o);
|
||||
o.P=new PointObject[P.length];
|
||||
for (int i=0; i<P.length; i++) {
|
||||
o.P[i]=P[i];
|
||||
}
|
||||
o.translateConditionals();
|
||||
o.translate();
|
||||
o.setName();
|
||||
o.updateText();
|
||||
o.setBreak(false);
|
||||
// o.setTarget(false); Dibs
|
||||
return o;
|
||||
} catch (final Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onlynearto(final int x, final int y, final ZirkelCanvas zc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final ConstructionObject o) {
|
||||
if (!(o instanceof QuadricObject)||!o.valid()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
for (int i=0; i<6; i++) {
|
||||
if (!equals(X[i], ((QuadricObject) o).X[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (final RuntimeException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUnit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void keepBaricentricCoords(final PointObject P) {
|
||||
if (!P.isPointOn()) {
|
||||
return;
|
||||
}
|
||||
if (P.BarycentricCoordsInitialzed) {
|
||||
final PointObject AA=this.P[0];
|
||||
final PointObject BB=this.P[1];
|
||||
final PointObject CC=this.P[2];
|
||||
final double xa=AA.getX(), ya=AA.getY();
|
||||
final double xb=BB.getX(), yb=BB.getY();
|
||||
final double xc=CC.getX(), yc=CC.getY();
|
||||
|
||||
final double xm=xa+P.Gx*(xb-xa)+P.Gy*(xc-xa);
|
||||
final double ym=ya+P.Gx*(yb-ya)+P.Gy*(yc-ya);
|
||||
|
||||
P.move(xm, ym);
|
||||
} else {
|
||||
P.computeBarycentricCoords();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistance(final PointObject P) {
|
||||
final double a=X[0], b=X[1], c=X[2], d=X[3], e=X[4], r=X[5];
|
||||
final double xc=P.getX(), yc=P.getY();
|
||||
if (Math.abs(a*xc*xc+b*yc*yc+c*xc+d*yc+e*xc*yc
|
||||
+r)<1e-13) // close enough
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
final double t[]=new double[5], s[]=new double[5];
|
||||
// Coefficients for fourth order polynomial for lambda (Lagrange factor)
|
||||
// Minimize (x-xc)^2+(y-yc)^2 with a*x^2+b*y^2+c*x+d*y+e*x*y+r=0
|
||||
// Computed with Maple
|
||||
t[0]=a*e*e*d*d-4*a*b*b*c*c+4*a*e*d*b
|
||||
*c-4*b*a*a*d*d+b*c*c*e*e-c
|
||||
*Math.pow(e, 3)*d+r*Math.pow(e, 4)-8*r*e*e*b
|
||||
*a+16*r*b*b*a*a;
|
||||
t[1]=8*b*b*c*c+8*a*a*d*d-8*e*d*b*c-8
|
||||
*a*d*c*e+8*r*e*e*b+8*a*b*c*c+8*b
|
||||
*a*d*d+8*r*e*e*a-32*r*b*b*a-32*r
|
||||
*b*a*a;
|
||||
t[2]=12*e*d*c+16*r*b*b-4*b*d*d-8*r*e*e
|
||||
+4*e*e*d*yc+16*b*b*xc*c-16*b*c*c
|
||||
-16*a*d*d-4*a*c*c+16*r*a*a+16*a*a
|
||||
*d*yc+4*xc*e*e*c-8*e*d*b*xc-8*e*yc
|
||||
*b*c-8*a*d*xc*e-8*a*yc*c*e+16*a*b
|
||||
*b*xc*xc-4*a*e*e*yc*yc+16*b*a*a*yc
|
||||
*yc-4*b*xc*xc*e*e+4*Math.pow(e, 3)*yc*xc
|
||||
+64*r*b*a-16*a*b*xc*e*yc;
|
||||
t[3]=-32*r*b+8*d*d+8*c*c+16*e*d*xc+8*e
|
||||
*e*yc*yc+8*xc*xc*e*e-32*r*a-32*b*xc
|
||||
*c+16*e*yc*c-32*a*d*yc-32*a*b*xc*xc
|
||||
-32*b*a*yc*yc;
|
||||
t[4]=16*b*yc*yc+16*d*yc+16*c*xc+16*xc*e*yc
|
||||
+16*r+16*a*xc*xc;
|
||||
final int k=Quartic.solve(t, s);
|
||||
// System.out.println(k+"Solutions found.");
|
||||
double dmin=1e30, xmin=xc, ymin=yc;
|
||||
for (int i=0; i<k; i++) // Choose closest solution of Lagrange
|
||||
// equation
|
||||
{
|
||||
final double l=s[i];
|
||||
// Solve for x,y when lambda is known.
|
||||
// Computed with Maple
|
||||
final double px=-(-e*d+4*b*l*xc-2*e*l*yc-4
|
||||
*l*l*xc+2*b*c-2*l*c)
|
||||
/(-e*e+4*b*a-4*b*l-4*l*a+4*l*l);
|
||||
final double py=-(2*a*d+4*a*l*yc-2*l*d-4*l
|
||||
*l*yc-2*l*xc*e-c*e)
|
||||
/(-e*e+4*b*a-4*b*l-4*l*a+4*l*l);
|
||||
final double dist=(px-xc)*(px-xc)+(py-yc)*(py-yc);
|
||||
if (dist<dmin) {
|
||||
dmin=dist;
|
||||
xmin=px;
|
||||
ymin=py;
|
||||
}
|
||||
}
|
||||
|
||||
final double dd=Math.sqrt((P.getX()-xmin)*(P.getX()-xmin)
|
||||
+(P.getY()-ymin)*(P.getY()-ymin));
|
||||
return (int) Math.round(dd*Cn.getPixel());
|
||||
}
|
||||
|
||||
public void project(final PointObject P) {
|
||||
keepBaricentricCoords(P);
|
||||
final double a=X[0], b=X[1], c=X[2], d=X[3], e=X[4], r=X[5];
|
||||
final double xc=P.getX(), yc=P.getY();
|
||||
if (Math.abs(a*xc*xc+b*yc*yc+c*xc+d*yc+e*xc*yc
|
||||
+r)<1e-13) // close enough
|
||||
{
|
||||
return;
|
||||
}
|
||||
final double t[]=new double[5], s[]=new double[5];
|
||||
// Coefficients for fourth order polynomial for lambda (Lagrange factor)
|
||||
// Minimize (x-xc)^2+(y-yc)^2 with a*x^2+b*y^2+c*x+d*y+e*x*y+r=0
|
||||
// Computed with Maple
|
||||
t[0]=a*e*e*d*d-4*a*b*b*c*c+4*a*e*d*b
|
||||
*c-4*b*a*a*d*d+b*c*c*e*e-c
|
||||
*Math.pow(e, 3)*d+r*Math.pow(e, 4)-8*r*e*e*b
|
||||
*a+16*r*b*b*a*a;
|
||||
t[1]=8*b*b*c*c+8*a*a*d*d-8*e*d*b*c-8
|
||||
*a*d*c*e+8*r*e*e*b+8*a*b*c*c+8*b
|
||||
*a*d*d+8*r*e*e*a-32*r*b*b*a-32*r
|
||||
*b*a*a;
|
||||
t[2]=12*e*d*c+16*r*b*b-4*b*d*d-8*r*e*e
|
||||
+4*e*e*d*yc+16*b*b*xc*c-16*b*c*c
|
||||
-16*a*d*d-4*a*c*c+16*r*a*a+16*a*a
|
||||
*d*yc+4*xc*e*e*c-8*e*d*b*xc-8*e*yc
|
||||
*b*c-8*a*d*xc*e-8*a*yc*c*e+16*a*b
|
||||
*b*xc*xc-4*a*e*e*yc*yc+16*b*a*a*yc
|
||||
*yc-4*b*xc*xc*e*e+4*Math.pow(e, 3)*yc*xc
|
||||
+64*r*b*a-16*a*b*xc*e*yc;
|
||||
t[3]=-32*r*b+8*d*d+8*c*c+16*e*d*xc+8*e
|
||||
*e*yc*yc+8*xc*xc*e*e-32*r*a-32*b*xc
|
||||
*c+16*e*yc*c-32*a*d*yc-32*a*b*xc*xc
|
||||
-32*b*a*yc*yc;
|
||||
t[4]=16*b*yc*yc+16*d*yc+16*c*xc+16*xc*e*yc
|
||||
+16*r+16*a*xc*xc;
|
||||
final int k=Quartic.solve(t, s);
|
||||
// System.out.println(k+"Solutions found.");
|
||||
double dmin=1e30, xmin=xc, ymin=yc;
|
||||
for (int i=0; i<k; i++) // Choose closest solution of Lagrange
|
||||
// equation
|
||||
{
|
||||
final double l=s[i];
|
||||
// Solve for x,y when lambda is known.
|
||||
// Computed with Maple
|
||||
final double px=-(-e*d+4*b*l*xc-2*e*l*yc-4
|
||||
*l*l*xc+2*b*c-2*l*c)
|
||||
/(-e*e+4*b*a-4*b*l-4*l*a+4*l*l);
|
||||
final double py=-(2*a*d+4*a*l*yc-2*l*d-4*l
|
||||
*l*yc-2*l*xc*e-c*e)
|
||||
/(-e*e+4*b*a-4*b*l-4*l*a+4*l*l);
|
||||
final double dist=(px-xc)*(px-xc)+(py-yc)*(py-yc);
|
||||
if (dist<dmin) {
|
||||
dmin=dist;
|
||||
xmin=px;
|
||||
ymin=py;
|
||||
}
|
||||
}
|
||||
P.move(xmin, ymin);
|
||||
}
|
||||
|
||||
public void project(final PointObject P, final double alpha) {
|
||||
project(P);
|
||||
}
|
||||
|
||||
public void dragTo(final double x, final double y) {
|
||||
for (int i=0; i<5; i++) {
|
||||
P[i].move(xd[i]+(x-x1), yd[i]+(y-y1));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(final double x, final double y) {
|
||||
}
|
||||
|
||||
public boolean moveable() {
|
||||
for (int i=0; i<5; i++) {
|
||||
if (!P[i].moveable()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
double xd[], yd[], x1, y1;
|
||||
|
||||
public void startDrag(final double x, final double y) {
|
||||
if (xd==null) {
|
||||
xd=new double[5];
|
||||
yd=new double[5];
|
||||
}
|
||||
for (int i=0; i<5; i++) {
|
||||
xd[i]=P[i].getX();
|
||||
yd[i]=P[i].getY();
|
||||
}
|
||||
x1=x;
|
||||
y1=y;
|
||||
}
|
||||
|
||||
public double getOldX() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double getOldY() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void snap(final ZirkelCanvas zc) {
|
||||
if (moveable()) {
|
||||
for (int i=0; i<5; i++) {
|
||||
P[i].snap(zc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canInteresectWith(final ConstructionObject o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void repulse(final PointObject P) {
|
||||
project(P);
|
||||
}
|
||||
|
||||
public PointObject[] getP() {
|
||||
return P;
|
||||
}
|
||||
}
|
||||
296
rene/zirkel/objects/QuadricQuadricIntersectionObject.java
Normal file
296
rene/zirkel/objects/QuadricQuadricIntersectionObject.java
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
/*
|
||||
|
||||
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: LineCircleIntersectionObject.java
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.structures.Coordinates4;
|
||||
import rene.zirkel.structures.CoordinatesXY;
|
||||
|
||||
public class QuadricQuadricIntersectionObject extends IntersectionObject {
|
||||
|
||||
private int Rank; //numéro de l'intersection, à savoir 0,1,2 ou 3
|
||||
|
||||
public QuadricQuadricIntersectionObject(final Construction c,
|
||||
final QuadricObject P1, final QuadricObject P2,
|
||||
final int rank) {
|
||||
super(c, P1, P2);
|
||||
Rank=rank;
|
||||
validate();
|
||||
}
|
||||
|
||||
// public void updateCircleDep ()
|
||||
// { ((QuadricObject)P2).addDep(this);
|
||||
// ((PrimitiveLineObject)P1).addDep(this);
|
||||
// }
|
||||
@Override
|
||||
public void validate() {
|
||||
final boolean oldvalid=Valid;
|
||||
if (!P1.valid()||!P2.valid()) {
|
||||
Valid=false;
|
||||
} else {
|
||||
Valid=true;
|
||||
}
|
||||
if (!Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ArrayList<CoordinatesXY> c=QuadricObject.intersect((QuadricObject) P1, (QuadricObject) P2);
|
||||
Collections.sort(c);
|
||||
|
||||
if (Double.isNaN(c.get(Rank).X)) {
|
||||
if (oldvalid&&getConstruction().shouldSwitch()) {
|
||||
doSwitch();
|
||||
if (!getConstruction().noteSwitch()) {
|
||||
Switched=false;
|
||||
}
|
||||
}
|
||||
;
|
||||
Valid=false;
|
||||
return;
|
||||
}
|
||||
setXY(c.get(Rank).X, c.get(Rank).Y);
|
||||
if (((QuadricObject) P1).getP()[0].is3D()||((QuadricObject) P1).getP()[1].is3D()||((QuadricObject) P1).getP()[2].is3D()||((QuadricObject) P1).getP()[3].is3D()||((QuadricObject) P1).getP()[4].is3D()||
|
||||
((QuadricObject) P2).getP()[0].is3D()||((QuadricObject) P2).getP()[1].is3D()||((QuadricObject) P2).getP()[2].is3D()||((QuadricObject) P2).getP()[3].is3D()||((QuadricObject) P2).getP()[4].is3D()) {
|
||||
try {
|
||||
double x0=((QuadricObject) P1).getP()[0].getX3D();
|
||||
double y0=((QuadricObject) P1).getP()[0].getY3D();
|
||||
double z0=((QuadricObject) P1).getP()[0].getZ3D();
|
||||
double x1=((QuadricObject) P1).getP()[1].getX3D();
|
||||
double y1=((QuadricObject) P1).getP()[1].getY3D();
|
||||
double z1=((QuadricObject) P1).getP()[1].getZ3D();
|
||||
double x2=((QuadricObject) P1).getP()[2].getX3D();
|
||||
double y2=((QuadricObject) P1).getP()[2].getY3D();
|
||||
double z2=((QuadricObject) P1).getP()[2].getZ3D();
|
||||
double x_O=getConstruction().find("O").getX();
|
||||
double x_X=getConstruction().find("X").getX();
|
||||
double x_Y=getConstruction().find("Y").getX();
|
||||
double x_Z=getConstruction().find("Z").getX();
|
||||
double y_O=getConstruction().find("O").getY();
|
||||
double y_X=getConstruction().find("X").getY();
|
||||
double y_Y=getConstruction().find("Y").getY();
|
||||
double y_Z=getConstruction().find("Z").getY();
|
||||
double coeffa=(x1-x0)*(x_X-x_O)+(y1-y0)*(x_Y-x_O)+(z1-z0)*(x_Z-x_O);
|
||||
double coeffb=(x2-x0)*(x_X-x_O)+(y2-y0)*(x_Y-x_O)+(z2-z0)*(x_Z-x_O);
|
||||
double coeffc=(x1-x0)*(y_X-y_O)+(y1-y0)*(y_Y-y_O)+(z1-z0)*(y_Z-y_O);
|
||||
double coeffd=(x2-x0)*(y_X-y_O)+(y2-y0)*(y_Y-y_O)+(z2-z0)*(y_Z-y_O);
|
||||
double coeffe=getX()-x_O-x0*(x_X-x_O)-y0*(x_Y-x_O)-z0*(x_Z-x_O);
|
||||
double coefff=getY()-y_O-x0*(y_X-y_O)-y0*(y_Y-y_O)-z0*(y_Z-y_O);
|
||||
double alpha1=(coeffe*coeffd-coefff*coeffb)/(coeffa*coeffd-coeffb*coeffc);
|
||||
double beta1=(coeffa*coefff-coeffc*coeffe)/(coeffa*coeffd-coeffb*coeffc);
|
||||
final double xM=x0+alpha1*(x1-x0)+beta1*(x2-x0);
|
||||
final double yM=y0+alpha1*(y1-y0)+beta1*(y2-y0);
|
||||
final double zM=z0+alpha1*(z1-z0)+beta1*(z2-z0);
|
||||
setX3D(xM);
|
||||
setY3D(yM);
|
||||
setZ3D(zM);
|
||||
setIs3D(true);
|
||||
} catch (final Exception eBary) {
|
||||
}
|
||||
// si les intersections n'existent pas en 3D, on les rendra superhidden
|
||||
try { // Dibs intersection 3D de cercles
|
||||
double a1=((QuadricObject) P1).getP()[0].getX3D();
|
||||
double b1=((QuadricObject) P1).getP()[0].getY3D();
|
||||
double c1=((QuadricObject) P1).getP()[0].getZ3D();
|
||||
double a2=((QuadricObject) P1).getP()[1].getX3D();
|
||||
double b2=((QuadricObject) P1).getP()[1].getY3D();
|
||||
double c2=((QuadricObject) P1).getP()[1].getZ3D();
|
||||
double a3=((QuadricObject) P1).getP()[2].getX3D();
|
||||
double b3=((QuadricObject) P1).getP()[2].getY3D();
|
||||
double c3=((QuadricObject) P1).getP()[2].getZ3D();
|
||||
double a1b=((QuadricObject) P2).getP()[0].getX3D();
|
||||
double b1b=((QuadricObject) P2).getP()[0].getY3D();
|
||||
double c1b=((QuadricObject) P2).getP()[0].getZ3D();
|
||||
double a2b=((QuadricObject) P2).getP()[1].getX3D();
|
||||
double b2b=((QuadricObject) P2).getP()[1].getY3D();
|
||||
double c2b=((QuadricObject) P2).getP()[1].getZ3D();
|
||||
double a3b=((QuadricObject) P2).getP()[2].getX3D();
|
||||
double b3b=((QuadricObject) P2).getP()[2].getY3D();
|
||||
double c3b=((QuadricObject) P2).getP()[2].getZ3D();
|
||||
double a4=(a1+a2)/2, b4=(b1+b2)/2, c4=(c1+c2)/2;
|
||||
double a4b=(a1b+a2b)/2, b4b=(b1b+b2b)/2, c4b=(c1b+c2b)/2;
|
||||
double a5=(a1+a3)/2, b5=(b1+b3)/2, c5=(c1+c3)/2;
|
||||
double a5b=(a1b+a3b)/2, b5b=(b1b+b3b)/2, c5b=(c1b+c3b)/2;
|
||||
double a6=a2-a1, b6=b2-b1, c6=c2-c1;
|
||||
double a6b=a2b-a1b, b6b=b2b-b1b, c6b=c2b-c1b;
|
||||
double a7=a3-a1, b7=b3-b1, c7=c3-c1;
|
||||
double a7b=a3b-a1b, b7b=b3b-b1b, c7b=c3b-c1b;
|
||||
double a8=b6*c7-c6*b7, b8=c6*a7-a6*c7, c8=a6*b7-b6*a7;
|
||||
double a8b=b6b*c7b-c6b*b7b, b8b=c6b*a7b-a6b*c7b, c8b=a6b*b7b-b6b*a7b;
|
||||
double a9=b8*c6-c8*b6, b9=c8*a6-a8*c6, c9=a8*b6-b8*a6;
|
||||
double a9b=b8b*c6b-c8b*b6b, b9b=c8b*a6b-a8b*c6b, c9b=a8b*b6b-b8b*a6b;
|
||||
double a10=b7*c8-c7*b8, b10=c7*a8-a7*c8, c10=a7*b8-b7*a8;
|
||||
double a10b=b7b*c8b-c7b*b8b, b10b=c7b*a8b-a7b*c8b, c10b=a7b*b8b-b7b*a8b;
|
||||
double a11=a5-a4, b11=b5-b4, c11=c5-c4;
|
||||
double a11b=a5b-a4b, b11b=b5b-b4b, c11b=c5b-c4b;
|
||||
double det1=b9*a10-a9*b10;
|
||||
double det1b=b9b*a10b-a9b*b10b;
|
||||
double det2=a10*b11-b10*a11;
|
||||
double det2b=a10b*b11b-b10b*a11b;
|
||||
double a12=a4+det2/det1*a9, b12=b4+det2/det1*b9, c12=c4+det2/det1*c9; // centre
|
||||
double a12b=a4b+det2b/det1b*a9b, b12b=b4b+det2b/det1b*b9b, c12b=c4b+det2b/det1b*c9b;
|
||||
double rcarre=(a12-a1)*(a12-a1)+(b12-b1)*(b12-b1)+(c12-c1)*(c12-c1); //rayons^2
|
||||
double rbcarre=(a12b-a1)*(a12b-a1)+(b12b-b1)*(b12b-b1)+(c12b-c1)*(c12b-c1);
|
||||
double n8=Math.sqrt(a8*a8+b8*b8+c8*c8);
|
||||
double n8b=Math.sqrt(a8b*a8b+b8b*b8b+c8b*c8b);
|
||||
a8 /=n8; b8 /= n8; c8 /= n8; // on norme P8
|
||||
a8b /=n8b; b8b /= n8b; c8b /= n8b;
|
||||
double a13=b8*c8b-c8*b8b, b13=c8*a8b-a8*c8b, c13=a8*b8b-b8*a8b; // pvect de pvects
|
||||
double n13carre=a13*a13+b13*b13+c13*c13;
|
||||
if (n13carre<1e-9) { // coplanaires
|
||||
double dcentrescarre=(a12b-a12)*(a12b-a12)+(b12b-b12)*(b12b-b12)+(c12b-c12)*(c12b-c12);
|
||||
double abs=(dcentrescarre+rcarre-rbcarre)/(2*Math.sqrt(dcentrescarre));
|
||||
if (rcarre-abs*abs<=0) {
|
||||
setSuperHidden(true);
|
||||
}
|
||||
else {
|
||||
double ord=Math.sqrt(rcarre-abs*abs);
|
||||
double a14=a12b-a12, b14=b12b-b12, c14=c12b-c12;
|
||||
double a15=b8*c14-c8*b14, b15=c8*a14-a8*c14, c15=a8*b14-b8*a14;
|
||||
double n14=Math.sqrt(a14*a14+b14*b14+c14*c14);
|
||||
double n15=Math.sqrt(a15*a15+b15*b15+c15*c15);
|
||||
a14/=n14; b14/=n14; c14/=n14;
|
||||
a15/=n15; b15/=n15; c15/=n15;
|
||||
double a16=a12+abs*a14+ord*a15, b16=b12+abs*b14+ord*b15, c16=c12+abs*c14+ord*c15;
|
||||
double a17=a12+abs*a14-ord*a15, b17=b12+abs*b14-ord*b15, c17=c12+abs*c14-ord*c15;
|
||||
final double xO=getConstruction().find("O").getX();
|
||||
final double yO=getConstruction().find("O").getY();
|
||||
final double deltaxX=getConstruction().find("X").getX()-xO;
|
||||
final double deltaxY=getConstruction().find("Y").getX()-xO;
|
||||
final double deltaxZ=getConstruction().find("Z").getX()-xO;
|
||||
final double deltayX=getConstruction().find("X").getY()-yO;
|
||||
final double deltayY=getConstruction().find("Y").getY()-yO;
|
||||
final double deltayZ=getConstruction().find("Z").getY()-yO;
|
||||
double posx=xO+a16*deltaxX+b16*deltaxY+c16*deltaxZ; // coordonnées 2D
|
||||
double posy=yO+a16*deltayX+b16*deltayY+c16*deltayZ;
|
||||
double erreurcarre=(c.get(Rank).X-posx)*(c.get(Rank).X-posx)+(c.get(Rank).Y-posy)*(c.get(Rank).Y-posy);
|
||||
if (erreurcarre<1e-8) {
|
||||
setX3D(a16);
|
||||
setY3D(b16);
|
||||
setZ3D(c16);
|
||||
}
|
||||
posx=xO+a17*deltaxX+b17*deltaxY+c17*deltaxZ; // coordonnées 2D 2eme sol
|
||||
posy=yO+a17*deltayX+b17*deltayY+c17*deltayZ;
|
||||
erreurcarre=(c.get(Rank).X-posx)*(c.get(Rank).X-posx)+(c.get(Rank).Y-posy)*(c.get(Rank).Y-posy);
|
||||
if (erreurcarre<1e-8) {
|
||||
setX3D(a17);
|
||||
setY3D(b17);
|
||||
setZ3D(c17);
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // pas coplanaires
|
||||
boolean isGood=false;
|
||||
double a14=a1b-a1, b14=b1b-b1, c14=c1b-c1;
|
||||
double x1=(a14*(b7*c6b-b6b*c7)+a6b*(b14*c7-b7*c14)+a7*(b6b*c14-b14*c6b))/(a6*(b7*c6b-b6b*c7)+a6b*(b6*c7-b7*c6)+a7*(b6b*c6-b6*c6b));
|
||||
double x2=(a14*(b6b*c6-b6*c6b)+a6*(b14*c6b-b6b*c14)+a6b*(b6*c14-b14*c6))/(a6*(b7*c6b-b6b*c7)+a6b*(b6*c7-b7*c6)+a7*(b6b*c6-b6*c6b));
|
||||
double y1=(a6b*(b7b*c7-b7*c7b)+a7*(b6b*c7b-b7b*c6b)+a7b*(b7*c6b-b6b*c7)+a14*(b7*c6b-b6b*c7)+a6b*(b14*c7-b7*c14)+a7*(b6b*c14-b14*c6b))/(a6*(b7*c6b-b6b*c7)+a6b*(b6*c7-b7*c6)+a7*(b6b*c6-b6*c6b));
|
||||
double y2=(a6*(b7b*c6b-b6b*c7b)+a6b*(b6*c7b-b7b*c6)+a7b*(b6b*c6-b6*c6b)+a14*(b6b*c6-b6*c6b)+a6*(b14*c6b-b6b*c14)+a6b*(b6*c14-b14*c6))/(a6*(b7*c6b-b6b*c7)+a6b*(b6*c7-b7*c6)+a7*(b6b*c6-b6*c6b));
|
||||
double a15=a1+x1*a6+x2*a7, b15=b1+x1*b6+x2*b7, c15=c1+x1*c6+x2*c7;
|
||||
double a16=a1+y1*a6+y2*a7, b16=b1+y1*b6+y2*b7, c16=c1+y1*c6+y2*c7;
|
||||
double a17=a16-a15, b17=b16-b15, c17=c16-c15;
|
||||
double a18=a15-a12, b18=b15-b12, c18=c15-c2;
|
||||
try {
|
||||
double x3=-(Math.sqrt((c17*c17+b17*b17+a17*a17)*rcarre+(-b17*b17-a17*a17)*c18*c18+(2*b17*b18+2*a17*a18)*c17*c18+(-b18*b18-a18*a18)*c17*c17-a17*a17*b18*b18+2*a17*a18*b17*b18-a18*a18*b17*b17)+c17*c18+b17*b18+a17*a18)/(c17*c17+b17*b17+a17*a17);
|
||||
double x4=(Math.sqrt((c17*c17+b17*b17+a17*a17)*rcarre+(-b17*b17-a17*a17)*c18*c18+(2*b17*b18+2*a17*a18)*c17*c18+(-b18*b18-a18*a18)*c17*c17-a17*a17*b18*b18+2*a17*a18*b17*b18-a18*a18*b17*b17)-c17*c18-b17*b18-a17*a18)/(c17*c17+b17*b17+a17*a17);
|
||||
double a19=a15+x3*a17, b19=b15+x3*b17, c19=c15+x3*c17; // soluces potentielles
|
||||
double a20=a15+x4*a17, b20=b15+x4*b17, c20=c15+x4*c17;
|
||||
double db19carre=(a19-a12b)*(a19-a12b)+(b19-b12b)*(b19-b12b)+(c19-c12b)*(c19-c12b);
|
||||
double db20carre=(a20-a12b)*(a20-a12b)+(b20-b12b)*(b20-b12b)+(c20-c12b)*(c20-c12b);
|
||||
if (Math.abs(db19carre-rbcarre)<1e-10) { // OK pour P19
|
||||
final double xO=getConstruction().find("O").getX();
|
||||
final double yO=getConstruction().find("O").getY();
|
||||
final double deltaxX=getConstruction().find("X").getX()-xO;
|
||||
final double deltaxY=getConstruction().find("Y").getX()-xO;
|
||||
final double deltaxZ=getConstruction().find("Z").getX()-xO;
|
||||
final double deltayX=getConstruction().find("X").getY()-yO;
|
||||
final double deltayY=getConstruction().find("Y").getY()-yO;
|
||||
final double deltayZ=getConstruction().find("Z").getY()-yO;
|
||||
double posx=xO+a19*deltaxX+b19*deltaxY+c19*deltaxZ; // coordonnées 2D
|
||||
double posy=yO+a19*deltayX+b19*deltayY+c19*deltayZ;
|
||||
double erreurcarre=(c.get(Rank).X-posx)*(c.get(Rank).X-posx)+(c.get(Rank).Y-posy)*(c.get(Rank).Y-posy);
|
||||
if (erreurcarre<1e-8) {
|
||||
isGood=true;
|
||||
setX3D(a19);
|
||||
setY3D(b19);
|
||||
setZ3D(c19);
|
||||
}
|
||||
else if (Math.abs(db20carre-rbcarre)<1e-8) {
|
||||
posx=xO+a20*deltaxX+b20*deltaxY+c20*deltaxZ; // coordonnées 2D
|
||||
posy=yO+a20*deltayX+b20*deltayY+c20*deltayZ;
|
||||
erreurcarre=(c.get(Rank).X-posx)*(c.get(Rank).X-posx)+(c.get(Rank).Y-posy)*(c.get(Rank).Y-posy);
|
||||
if (erreurcarre<1e-8) {
|
||||
isGood=true;
|
||||
setX3D(a20);
|
||||
setY3D(b20);
|
||||
setZ3D(c20);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Math.abs(db20carre-rbcarre)<1e-8) { // OK pour P20
|
||||
final double xO=getConstruction().find("O").getX();
|
||||
final double yO=getConstruction().find("O").getY();
|
||||
final double deltaxX=getConstruction().find("X").getX()-xO;
|
||||
final double deltaxY=getConstruction().find("Y").getX()-xO;
|
||||
final double deltaxZ=getConstruction().find("Z").getX()-xO;
|
||||
final double deltayX=getConstruction().find("X").getY()-yO;
|
||||
final double deltayY=getConstruction().find("Y").getY()-yO;
|
||||
final double deltayZ=getConstruction().find("Z").getY()-yO;
|
||||
double posx=xO+a20*deltaxX+b20*deltaxY+c20*deltaxZ; // coordonnées 2D
|
||||
double posy=yO+a20*deltayX+b20*deltayY+c20*deltayZ;
|
||||
double erreurcarre=(c.get(Rank).X-posx)*(c.get(Rank).X-posx)+(c.get(Rank).Y-posy)*(c.get(Rank).Y-posy);
|
||||
if (erreurcarre<1e-10) {
|
||||
isGood=true;
|
||||
setX3D(a20);
|
||||
setY3D(b20);
|
||||
setZ3D(c20);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final Exception ex) {
|
||||
setSuperHidden(true);
|
||||
}
|
||||
if (!isGood) setSuperHidden(true);
|
||||
}
|
||||
|
||||
} catch (final Exception ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
super.printArgs(xml);
|
||||
xml.printArg("which", ""+Rank);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSwitchable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAlternate() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
305
rene/zirkel/objects/RayObject.java
Normal file
305
rene/zirkel/objects/RayObject.java
Normal file
|
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
|
||||
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: SegmentObject.java
|
||||
|
||||
import rene.gui.Global;
|
||||
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.graphics.MyGraphics;
|
||||
import rene.zirkel.graphics.MainGraphics;
|
||||
import rene.zirkel.structures.Coordinates;
|
||||
|
||||
|
||||
public class RayObject extends TwoPointLineObject {
|
||||
static Count N = new Count();
|
||||
|
||||
public RayObject(final Construction c, final PointObject p1,
|
||||
final PointObject p2) {
|
||||
super(c, p1, p2);
|
||||
validate();
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Ray";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getN() {
|
||||
return N.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaults() {
|
||||
setShowName(Global.getParameter("options.line.shownames", false));
|
||||
setShowValue(Global.getParameter("options.line.showvalues", false));
|
||||
setColor(Global.getParameter("options.line.color", 0));
|
||||
setColorType(Global.getParameter("options.line.colortype", 0));
|
||||
setHidden(Cn.Hidden);
|
||||
setObtuse(Cn.Obtuse);
|
||||
setSolid(Cn.Solid);
|
||||
setLarge(Global.getParameter("options.line.large", false));
|
||||
setBold(Global.getParameter("options.line.bold", false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetDefaults() {
|
||||
setShowName(Global.getParameter("options.line.shownames", false));
|
||||
setShowValue(Global.getParameter("options.line.showvalues", false));
|
||||
setColor(Global.getParameter("options.line.color", 0));
|
||||
setColorType(Global.getParameter("options.line.colortype", 0));
|
||||
setLarge(Global.getParameter("options.line.large", false));
|
||||
setBold(Global.getParameter("options.line.bold", false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
setText(text2(Global.name("text.ray"), P1.getName(), P2.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
// if ((P1==null)) {
|
||||
// System.out.println(this.getName()+" : "+P2.getName());
|
||||
// }
|
||||
// if ((P2==null)) {
|
||||
// System.out.println(this.getName()+" : "+P1.getName());
|
||||
// }
|
||||
|
||||
if (!P1.valid() || !P2.valid()) {
|
||||
Valid = false;
|
||||
return;
|
||||
} else {
|
||||
Valid = true;
|
||||
X1 = P1.getX();
|
||||
Y1 = P1.getY();
|
||||
X2 = P2.getX();
|
||||
Y2 = P2.getY();
|
||||
// compute normalized vector in the direction of the line:
|
||||
DX = X2 - X1;
|
||||
DY = Y2 - Y1;
|
||||
R = Math.sqrt(DX * DX + DY * DY);
|
||||
if (R < 1e-10) {
|
||||
Valid = false;
|
||||
return;
|
||||
}
|
||||
DX /= R;
|
||||
DY /= R;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(final MyGraphics g, final ZirkelCanvas zc) {
|
||||
if (!Valid || mustHide(zc))
|
||||
return;
|
||||
// compute middle of the screen:
|
||||
final double xm = (zc.minX() + zc.maxX()) / 2, ym = (zc.minY() + zc
|
||||
.maxY()) / 2;
|
||||
// compute distance from middle to line:
|
||||
final double d = (xm - X1) * DY - (ym - Y1) * DX;
|
||||
// compute point with minimal distance
|
||||
final double x = xm - d * DY, y = ym + d * DX;
|
||||
// compute size of the screen
|
||||
final double a = Math.max(zc.maxX() - zc.minX(), zc.maxY() - zc.minY());
|
||||
if (Math.abs(d) > a)
|
||||
return;
|
||||
// compute distance from closest point to source
|
||||
final double b = (x - X1) * DX + (y - Y1) * DY;
|
||||
// compute the two visible endpoints
|
||||
k1 = b - a;
|
||||
k2 = b + a;
|
||||
k12valid = true;
|
||||
if (k1 < 0)
|
||||
k1 = 0;
|
||||
if (k1 >= k2)
|
||||
return;
|
||||
if (Partial && !zc.showHidden() && Dep != null) {
|
||||
final double dd = (zc.maxX() - zc.minX()) / 20;
|
||||
double dmin = -dd, dmax = R + dd;
|
||||
for (int i = 0; i < NDep; i++) {
|
||||
if (!Dep[i].valid() || Dep[i].mustHide(zc))
|
||||
continue;
|
||||
final double s = project(Dep[i].getX(), Dep[i].getY());
|
||||
if (s - dd < dmin)
|
||||
dmin = s - dd;
|
||||
else if (s + dd > dmax)
|
||||
dmax = s + dd;
|
||||
}
|
||||
if (k1 < dmin)
|
||||
k1 = dmin;
|
||||
if (k2 > dmax)
|
||||
k2 = dmax;
|
||||
}
|
||||
final double c1 = zc.col(X1 + k1 * DX), c2 = zc.col(X1 + k2 * DX), r1 = zc
|
||||
.row(Y1 + k1 * DY), r2 = zc.row(Y1 + k2 * DY);
|
||||
// paint:
|
||||
if (isStrongSelected() && g instanceof MainGraphics) {
|
||||
((MainGraphics) g).drawMarkerLine(c1, r1, c2, r2);
|
||||
}
|
||||
g.setColor(this);
|
||||
if (visible(zc)) {
|
||||
if (tracked())
|
||||
zc.UniversalTrack.drawTrackLine(this, c1, r1, c2, r2);
|
||||
g.drawLine(c1, r1, c2, r2, this);
|
||||
}
|
||||
final String s = getDisplayText();
|
||||
if (!s.equals("")) {
|
||||
g.setLabelColor(this);
|
||||
DisplaysText = true;
|
||||
double c = -b + a / 5;
|
||||
if (c < -a / 5)
|
||||
c = -a / 5;
|
||||
else if (c > a / 5)
|
||||
c = a / 5;
|
||||
if (c < -b + a / 10)
|
||||
c = -b + a / 10;
|
||||
if (KeepClose) {
|
||||
final double side = (YcOffset < 0) ? 1 : -1;
|
||||
drawLabel(g, s, zc, X1 + XcOffset * (X2 - X1), Y1 + XcOffset
|
||||
* (Y2 - Y1), side * DX, side * DY, 0, 0);
|
||||
} else
|
||||
drawLabel(g, s, zc, x + c * DX, y + c * DY, DX, DY, XcOffset,
|
||||
YcOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canKeepClose() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setKeepClose(final double x, final double y) {
|
||||
KeepClose = true;
|
||||
XcOffset = (x - X1) / R * DX + (y - Y1) / R * DY;
|
||||
YcOffset = (x - X1) / R * DY - (y - Y1) / R * DX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayValue() {
|
||||
|
||||
return Global.getLocaleNumber(R, "lengths");
|
||||
}
|
||||
|
||||
//
|
||||
// public String getDisplayValue ()
|
||||
// { return ""+round(R,ZirkelCanvas.LengthsFactor);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int c, final int r, final ZirkelCanvas zc) {
|
||||
if (!displays(zc))
|
||||
return false;
|
||||
// compute point at c,r
|
||||
final double x = zc.x(c), y = zc.y(r);
|
||||
// compute distance from line
|
||||
double d = (x - X1) * DY - (y - Y1) * DX;
|
||||
// compute offset
|
||||
final double o = (x - X1) * DX + (y - Y1) * DY, o1 = (X2 - X1) * DX
|
||||
+ (Y2 - Y1) * DY;
|
||||
if (o1 > 0) {
|
||||
if (o < 0)
|
||||
d = Math.sqrt((x - X1) * (x - X1) + (y - Y1) * (y - Y1));
|
||||
} else {
|
||||
if (o > 0)
|
||||
d = Math.sqrt((x - X1) * (x - X1) + (y - Y1) * (y - Y1));
|
||||
}
|
||||
// test, if on visible part
|
||||
final double s = project(x, y);
|
||||
if (s < k1 || s > k2)
|
||||
return false;
|
||||
// scale in screen coordinates
|
||||
Value = Math.abs(zc.col(zc.minX() + d) - zc.col(zc.minX()));
|
||||
return Value < zc.selectionSize() * 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
xml.printArg("from", P1.getName());
|
||||
xml.printArg("to", P2.getName());
|
||||
super.printArgs(xml);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(final double x, final double y) {
|
||||
final double a = (x - X1) * DX + (y - Y1) * DY;
|
||||
if (a < 1e-9)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double project(final double x, final double y) {
|
||||
final double h = super.project(x, y);
|
||||
if (h < 0)
|
||||
return 0;
|
||||
return h;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final ConstructionObject o) {
|
||||
if (!(o instanceof RayObject) || !o.valid())
|
||||
return false;
|
||||
final RayObject l = (RayObject) o;
|
||||
return equals(X1, l.X1) && equals(Y1, l.Y1) && equals(DX, l.DX)
|
||||
&& equals(DY, l.DY);
|
||||
}
|
||||
|
||||
public static Coordinates intersect(final PrimitiveLineObject l1,
|
||||
final PrimitiveLineObject l2)
|
||||
// compute the intersection coordinates of two lines
|
||||
{
|
||||
final double det = -l1.DX * l2.DY + l1.DY * l2.DX;
|
||||
if (Math.abs(det) < 1e-10)
|
||||
return null;
|
||||
final double a = (-(l2.X1 - l1.X1) * l2.DY + (l2.Y1 - l1.Y1) * l2.DX)
|
||||
/ det;
|
||||
return new Coordinates(l1.X1 + a * l1.DX, l1.Y1 + a * l1.DY);
|
||||
}
|
||||
|
||||
public static Coordinates intersect(final PrimitiveLineObject l,
|
||||
final PrimitiveCircleObject c)
|
||||
// compute the intersection coordinates of a line with a circle
|
||||
{
|
||||
double x = c.getX(), y = c.getY();
|
||||
final double r = c.getR();
|
||||
final double d = (x - l.X1) * l.DY - (y - l.Y1) * l.DX;
|
||||
if (Math.abs(d) > r + 1e-10)
|
||||
return null;
|
||||
x -= d * l.DY;
|
||||
y += d * l.DX;
|
||||
double h = r * r - d * d;
|
||||
if (h > 0)
|
||||
h = Math.sqrt(h);
|
||||
else
|
||||
h = 0;
|
||||
return new Coordinates(x + h * l.DX, y + h * l.DY, x - h * l.DX, y - h
|
||||
* l.DY);
|
||||
}
|
||||
|
||||
}
|
||||
747
rene/zirkel/objects/SegmentObject.java
Normal file
747
rene/zirkel/objects/SegmentObject.java
Normal file
|
|
@ -0,0 +1,747 @@
|
|||
/*
|
||||
|
||||
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: SegmentObject.java
|
||||
import java.awt.Rectangle;
|
||||
import java.util.Enumeration;
|
||||
import rene.gui.Global;
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.zirkel.ZirkelCanvas;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.construction.ConstructionException;
|
||||
import rene.zirkel.construction.Count;
|
||||
import rene.zirkel.expression.Expression;
|
||||
import rene.zirkel.expression.ExpressionColor;
|
||||
import rene.zirkel.expression.InvalidException;
|
||||
import rene.zirkel.graphics.MainGraphics;
|
||||
import rene.zirkel.graphics.MyGraphics;
|
||||
|
||||
|
||||
/**
|
||||
* @author Rene Class for segments, derived from LineObject, TwoPointLineObject.
|
||||
* Segments override various methods from lines. They have a length.
|
||||
* Also the length can be fixed.
|
||||
*/
|
||||
public class SegmentObject extends TwoPointLineObject {
|
||||
|
||||
static Count N = new Count();
|
||||
protected boolean Is3D; //Dibs : 3D ?
|
||||
protected double X3D1, Y3D1, Z3D1, X3D2, Y3D2, Z3D2, DX3D, DY3D, DZ3D; //Dibs
|
||||
protected boolean Fixed = false; // fixed length?
|
||||
protected boolean Fixed3D = false; // fixed length?
|
||||
Expression E; // expression to fix the length.
|
||||
Expression E3D;
|
||||
boolean ExpressionFailed; // invalid expression?
|
||||
public boolean Arrow; // draw as arrow.
|
||||
int code_symbol = 0;
|
||||
|
||||
public SegmentObject(final Construction c, final PointObject p1,
|
||||
final PointObject p2) {
|
||||
super(c, p1, p2);
|
||||
if (p1.is3D()&&p2.is3D()) Is3D=true;
|
||||
Arrow = false;
|
||||
validate();
|
||||
updateText();
|
||||
Unit = Global.getParameter("unit.length", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCDPDisplayValue(){
|
||||
return Global.getLocaleNumber(R, "lengths");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Segment";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getN() {
|
||||
return N.next();
|
||||
}
|
||||
|
||||
// public void setDefaults ()
|
||||
// { Arrow=Cn.Vectors;
|
||||
// super.setDefaults();
|
||||
// }
|
||||
@Override
|
||||
public void setDefaults() {
|
||||
//Arrow = Cn.Vectors; //plus nécessaire
|
||||
setShowName(Global.getParameter("options.segment.shownames", false));
|
||||
setShowValue(Global.getParameter("options.segment.showvalues", false));
|
||||
setColor(Global.getParameter("options.segment.color", 0), Global
|
||||
.getParameter("options.segment.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.segment.colortype", 0));
|
||||
setHidden(Cn.Hidden);
|
||||
setObtuse(Cn.Obtuse);
|
||||
setSolid(Cn.Solid);
|
||||
setLarge(Global.getParameter("options.segment.large", false));
|
||||
setBold(Global.getParameter("options.segment.bold", false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetDefaults() {
|
||||
setShowName(Global.getParameter("options.segment.shownames", false));
|
||||
setShowValue(Global.getParameter("options.segment.showvalues", false));
|
||||
setColor(Global.getParameter("options.segment.color", 0), Global
|
||||
.getParameter("options.segment.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.segment.colortype", 0));
|
||||
setLarge(Global.getParameter("options.segment.large", false));
|
||||
setBold(Global.getParameter("options.segment.bold", false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
if (!Fixed) {
|
||||
setText(text2(Global.name("text.segment"), P1.getName(), P2
|
||||
.getName()));
|
||||
} else {
|
||||
if (E == null) {
|
||||
setText(text3(Global.name("text.segment.fixed"), P1.getName(),
|
||||
P2.getName(), "" + round(R)));
|
||||
} else {
|
||||
setText(text3(Global.name("text.segment.fixed"), P1.getName(),
|
||||
P2.getName(), "\"" + E.toString() + "\""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
ExpressionFailed = false;
|
||||
if (!P1.valid() || !P2.valid()) {
|
||||
Valid = false;
|
||||
return;
|
||||
} else {
|
||||
Valid = true;
|
||||
X1 = P1.getX();
|
||||
Y1 = P1.getY();
|
||||
X2 = P2.getX();
|
||||
Y2 = P2.getY();
|
||||
// compute normalized vector in the direction of the line:
|
||||
DX = X2 - X1;
|
||||
DY = Y2 - Y1;
|
||||
R = Math.sqrt(DX * DX + DY * DY);
|
||||
// System.out.println("X1="+X1+" Y1="+Y1+" | X2="+X2+" Y2="+Y2+" R="+R);
|
||||
if (P1.is3D()&&P2.is3D()) Is3D=true; // Dibs last updated
|
||||
if (Is3D) { //Dibs
|
||||
X3D1 = P1.getX3D();
|
||||
Y3D1 = P1.getY3D();
|
||||
Z3D1 = P1.getZ3D();
|
||||
X3D2 = P2.getX3D();
|
||||
Y3D2 = P2.getY3D();
|
||||
Z3D2 = P2.getZ3D();
|
||||
DX3D = X3D2-X3D1;
|
||||
DY3D = Y3D2-Y3D1;
|
||||
DZ3D = Z3D2-Z3D1;
|
||||
R3D = Math.sqrt(DX3D * DX3D + DY3D * DY3D + DZ3D * DZ3D);
|
||||
}
|
||||
|
||||
// if fixed, move the moveable endpoint.
|
||||
if (Fixed && E != null&&!is3D()) {
|
||||
try {
|
||||
final double FixedR = E.getValue();
|
||||
// System.out.println(R+" "+FixedR);
|
||||
if (FixedR < 1e-8) {
|
||||
R = 0;
|
||||
ExpressionFailed = true;
|
||||
Valid = false;
|
||||
return;
|
||||
}
|
||||
boolean movefirst = P1.moveableBy(this), movesecond = P2
|
||||
.moveableBy(this);
|
||||
if (P2.getBound() != null) {
|
||||
final ConstructionObject bound = P2.getBound();
|
||||
if (bound instanceof RayObject) {
|
||||
if (((RayObject) bound).getP1() == P1) {
|
||||
movesecond = true;
|
||||
}
|
||||
}
|
||||
} else if (P1.getBound() != null) {
|
||||
final ConstructionObject bound = P1.getBound();
|
||||
if (bound instanceof RayObject) {
|
||||
if (((RayObject) bound).getP1() == P2) {
|
||||
movefirst = true;
|
||||
movesecond = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (movesecond) {
|
||||
if (R < 1e-10) {
|
||||
P2.move(X1 + FixedR, Y1);
|
||||
} else {
|
||||
P2.move(X1 + FixedR * DX / R, Y1 + FixedR * DY / R);
|
||||
}
|
||||
P1.setUseAlpha(false);
|
||||
// System.out.println("Move "+P2.getName());
|
||||
} else if (movefirst) {
|
||||
if (R < 1e-10) {
|
||||
P1.move(X2 - FixedR, Y2);
|
||||
} else {
|
||||
P1.move(X2 - FixedR * DX / R, Y2 - FixedR * DY / R);
|
||||
}
|
||||
P2.setUseAlpha(false);
|
||||
// System.out.println("Move "+P1.getName());
|
||||
} else {
|
||||
Fixed = false; // no moveable endpoint!
|
||||
}
|
||||
if (Fixed) {
|
||||
X1 = P1.getX();
|
||||
Y1 = P1.getY();
|
||||
X2 = P2.getX();
|
||||
Y2 = P2.getY();
|
||||
DX = X2 - X1;
|
||||
DY = Y2 - Y1;
|
||||
R = Math.sqrt(DX * DX + DY * DY);
|
||||
P2.movedBy(this);
|
||||
P1.movedBy(this);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
ExpressionFailed = true;
|
||||
Valid = false;
|
||||
R = 0;
|
||||
R3D=0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (Fixed3D && E3D != null) { // pour plus tard...
|
||||
try {
|
||||
final double FixedR3D = E3D.getValue();
|
||||
if (FixedR3D < 1e-8) {
|
||||
R3D = 0;
|
||||
ExpressionFailed = true;
|
||||
Valid = false;
|
||||
return;
|
||||
}
|
||||
boolean movefirst = P1.moveableBy(this), movesecond = P2
|
||||
.moveableBy(this);
|
||||
if (P2.getBound() != null) {
|
||||
final ConstructionObject bound = P2.getBound();
|
||||
if (bound instanceof RayObject) {
|
||||
if (((RayObject) bound).getP1() == P1) {
|
||||
movesecond = true;
|
||||
}
|
||||
}
|
||||
} else if (P1.getBound() != null) {
|
||||
final ConstructionObject bound = P1.getBound();
|
||||
if (bound instanceof RayObject) {
|
||||
if (((RayObject) bound).getP1() == P2) {
|
||||
movefirst = true;
|
||||
movesecond = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (movesecond) {
|
||||
if (R3D < 1e-10) {
|
||||
P2.move3D(X3D1 + FixedR3D, Y3D1, Z3D1);
|
||||
} else {
|
||||
P2.move3D(X3D1 + FixedR3D * DX3D / R3D, Y3D1 + FixedR3D * DY3D / R3D, Z3D1 + FixedR3D * DZ3D / R3D);
|
||||
}
|
||||
P1.setUseAlpha(false);
|
||||
// System.out.println("Move "+P2.getName());
|
||||
} else if (movefirst) {
|
||||
if (R < 1e-10) {
|
||||
P1.move3D(X3D2 - FixedR3D, Y3D2, Z3D2);
|
||||
} else {
|
||||
P1.move3D(X3D2 - FixedR3D * DX3D / R3D, Y3D2 - FixedR3D * DY3D / R3D, Z3D2 - FixedR3D * DZ3D / R3D);
|
||||
}
|
||||
P2.setUseAlpha(false);
|
||||
// System.out.println("Move "+P1.getName());
|
||||
} else {
|
||||
Fixed3D = false; // no moveable endpoint!
|
||||
}
|
||||
if (Fixed3D) {
|
||||
X3D1 = P1.getX3D();
|
||||
Y3D1 = P1.getY3D();
|
||||
Z3D1 = P1.getZ3D();
|
||||
X3D2 = P2.getX3D();
|
||||
Y3D2 = P2.getY3D();
|
||||
Z3D2 = P2.getZ3D();
|
||||
DX3D = X3D2-X3D1;
|
||||
DY3D = Y3D2-Y3D1;
|
||||
DZ3D = Z3D2-Z3D1;
|
||||
R3D = Math.sqrt(DX3D * DX3D + DY3D * DY3D + DZ3D * DZ3D);
|
||||
P2.movedBy(this);
|
||||
P1.movedBy(this);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
ExpressionFailed = true;
|
||||
Valid = false;
|
||||
R = 0;
|
||||
R3D=0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// See of the length is too small.
|
||||
if (R < 1e-10) {
|
||||
R = 0;
|
||||
DX = 1;
|
||||
DY = 0;
|
||||
} else {
|
||||
DX /= R;
|
||||
DY /= R;
|
||||
}
|
||||
if (R3D < 1e-10) {
|
||||
R3D = 0;
|
||||
DX3D = 1;
|
||||
DY3D = 0;
|
||||
DZ3D=0;
|
||||
} else {
|
||||
DX3D /= R3D;
|
||||
DY3D /= R3D;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(final MyGraphics g, final ZirkelCanvas zc) {
|
||||
if (!Valid || mustHide(zc)) {
|
||||
return;
|
||||
}
|
||||
final double c1 = zc.col(X1), r1 = zc.row(Y1), c2 = zc.col(X2), r2 = zc
|
||||
.row(Y2);
|
||||
if (visible(zc)) {
|
||||
if (isStrongSelected() && g instanceof MainGraphics) {
|
||||
((MainGraphics) g).drawMarkerLine(c1, r1, c2, r2);
|
||||
}
|
||||
g.setColor(this);
|
||||
if (tracked()) {
|
||||
zc.UniversalTrack.drawTrackLine(this, c1, r1, c2, r2);
|
||||
}
|
||||
g.drawLine(c1, r1, c2, r2, this);
|
||||
|
||||
if (code_symbol > 0) {
|
||||
// length of the tick mark :
|
||||
final double rr = 7*Cn.getOne();
|
||||
// distance between two marks :
|
||||
final double dd = 3*Cn.getOne();
|
||||
// oblique de la marque :
|
||||
final double ob = 2*Cn.getOne();
|
||||
|
||||
final double cM = (c1 + c2) / 2, rM = (r1 + r2) / 2;
|
||||
final double A = c2 - cM, B = r2 - rM;
|
||||
final double sqrt2 = Math.sqrt(B * B + A * A);
|
||||
final double xx1 = -(rr * B) / sqrt2 + cM - ob * A / sqrt2;
|
||||
final double yy1 = (rr * A) / sqrt2 + rM - ob * B / sqrt2;
|
||||
final double xx2 = (rr * B) / sqrt2 + cM + ob * A / sqrt2;
|
||||
final double yy2 = -(rr * A) / sqrt2 + rM + ob * B / sqrt2;
|
||||
final double xt = dd * A / sqrt2, yt = dd * B / sqrt2;
|
||||
switch (code_symbol) {
|
||||
case 1:
|
||||
g.drawLine(xx1, yy1, xx2, yy2, this);
|
||||
break;
|
||||
case 2:
|
||||
g.drawLine(xx1 - xt, yy1 - yt, xx2 - xt, yy2 - yt, this);
|
||||
g.drawLine(xx1 + xt, yy1 + yt, xx2 + xt, yy2 + yt, this);
|
||||
break;
|
||||
case 3:
|
||||
g.drawLine(xx1 - 2 * xt, yy1 - 2 * yt, xx2 - 2 * xt, yy2
|
||||
- 2 * yt, this);
|
||||
g.drawLine(xx1, yy1, xx2, yy2, this);
|
||||
g.drawLine(xx1 + 2 * xt, yy1 + 2 * yt, xx2 + 2 * xt, yy2
|
||||
+ 2 * yt, this);
|
||||
break;
|
||||
case 4:
|
||||
g.drawLine(xx1 - 3 * xt, yy1 - 3 * yt, xx2 - 3 * xt, yy2
|
||||
- 3 * yt, this);
|
||||
g.drawLine(xx1 - xt, yy1 - yt, xx2 - xt, yy2 - yt, this);
|
||||
g.drawLine(xx1 + xt, yy1 + yt, xx2 + xt, yy2 + yt, this);
|
||||
g.drawLine(xx1 + 3 * xt, yy1 + 3 * yt, xx2 + 3 * xt, yy2
|
||||
+ 3 * yt, this);
|
||||
break;
|
||||
case 5:
|
||||
g.drawLine(xx1 - 2 * xt, yy1 - 2 * yt, xx2 + 2 * xt, yy2
|
||||
+ 2 * yt, this);
|
||||
g.drawLine(xx1 + 2 * xt, yy1 + 2 * yt, xx2 - 2 * xt, yy2
|
||||
- 2 * yt, this);
|
||||
break;
|
||||
case 6:
|
||||
g.drawCircle(cM, rM, 2 * dd, this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Arrow) // draw as arrow!
|
||||
{
|
||||
final double a = Math.PI * 0.9;
|
||||
final double r = zc.dx(Cn.getOne()*Global.getParameter(
|
||||
"arrowsize", 15)); // 10 pixel on the screen
|
||||
final double[] cols = new double[3];
|
||||
cols[0] = c2;
|
||||
cols[1] = zc
|
||||
.col(X2 + (DX * Math.cos(a) + DY * Math.sin(a)) * r);
|
||||
cols[2] = zc.col(X2 + (DX * Math.cos(-a) + DY * Math.sin(-a))
|
||||
* r);
|
||||
final double[] rows = new double[3];
|
||||
rows[0] = r2;
|
||||
rows[1] = zc.row(Y2 + (-DX * Math.sin(a) + DY * Math.cos(a))
|
||||
* r);
|
||||
rows[2] = zc.row(Y2 + (-DX * Math.sin(-a) + DY * Math.cos(-a))
|
||||
* r);
|
||||
g.fillPolygon(cols, rows, 3, true, false, this);
|
||||
}
|
||||
}
|
||||
final String s = getDisplayText();
|
||||
if (!s.equals("")) {
|
||||
g.setLabelColor(this);
|
||||
setFont(g);
|
||||
DisplaysText = true;
|
||||
if (KeepClose) {
|
||||
final double side = (YcOffset < 0) ? 1 : -1;
|
||||
drawLabel(g, s, zc, X1 + XcOffset * (X2 - X1), Y1 + XcOffset
|
||||
* (Y2 - Y1), side * DX, side * DY, 0, 0);
|
||||
} else {
|
||||
drawLabel(g, s, zc, (X1 + X2) / 2, (Y1 + Y2) / 2, DX, DY,
|
||||
XcOffset, YcOffset);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canKeepClose() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setKeepClose(final double x, final double y) {
|
||||
KeepClose = true;
|
||||
XcOffset = (x - X1) / R * DX + (y - Y1) / R * DY;
|
||||
YcOffset = (x - X1) / R * DY - (y - Y1) / R * DX;
|
||||
}
|
||||
|
||||
// public String getDisplayValue ()
|
||||
// { return
|
||||
// eric.JGlobals.fixDecimal(""+round(R,ZirkelCanvas.LengthsFactor));
|
||||
// }
|
||||
|
||||
@Override
|
||||
public String getDisplayValue() {
|
||||
// return ""+round(R,ZirkelCanvas.LengthsFactor);
|
||||
if (!Is3D) return Global.getLocaleNumber(R, "lengths");
|
||||
else return Global.getLocaleNumber(R3D, "lengths");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInRect(Rectangle r, ZirkelCanvas zc){
|
||||
return ((r.contains(zc.col(P1.getX()),zc.row(P1.getY())))&&
|
||||
(r.contains(zc.col(P2.getX()),zc.row(P2.getY()))));
|
||||
}
|
||||
|
||||
/**
|
||||
* see, if a point is on the segment or near to it.
|
||||
*/
|
||||
@Override
|
||||
public boolean nearto(final int c, final int r, final ZirkelCanvas zc) {
|
||||
if (ExpressionFailed && P1.valid()) {
|
||||
return P1.nearto(c, r, zc);
|
||||
}
|
||||
if (ExpressionFailed && P2.valid()) {
|
||||
return P2.nearto(c, r, zc);
|
||||
}
|
||||
if (!displays(zc)) {
|
||||
return false;
|
||||
}
|
||||
// compute point at c,r
|
||||
final double x = zc.x(c), y = zc.y(r);
|
||||
// compute distance from line
|
||||
double d = (x - X1) * DY - (y - Y1) * DX;
|
||||
// compute offset
|
||||
final double o = (x - X1) * DX + (y - Y1) * DY, o1 = (X2 - X1) * DX
|
||||
+ (Y2 - Y1) * DY;
|
||||
if (o1 > 0) {
|
||||
if (o > o1) {
|
||||
d = Math.sqrt((x - X2) * (x - X2) + (y - Y2) * (y - Y2));
|
||||
} else if (o < 0) {
|
||||
d = Math.sqrt((x - X1) * (x - X1) + (y - Y1) * (y - Y1));
|
||||
}
|
||||
} else {
|
||||
if (o < o1) {
|
||||
d = Math.sqrt((x - X2) * (x - X2) + (y - Y2) * (y - Y2));
|
||||
} else if (o > 0) {
|
||||
d = Math.sqrt((x - X1) * (x - X1) + (y - Y1) * (y - Y1));
|
||||
}
|
||||
}
|
||||
// scale in screen coordinates
|
||||
Value = Math.abs(zc.col(zc.minX() + d) - zc.col(zc.minX())) * 0.9;
|
||||
return Value < zc.selectionSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* true, if the segment is too small.
|
||||
*/
|
||||
@Override
|
||||
public boolean onlynearto(final int c, final int r, final ZirkelCanvas zc) {
|
||||
return R < zc.dx(3 *zc.pointSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
xml.printArg("from", P1.getName());
|
||||
xml.printArg("to", P2.getName());
|
||||
if (Is3D) {
|
||||
xml.printArg("is3D", "true");
|
||||
}
|
||||
if (Fixed && E != null) {
|
||||
xml.printArg("fixed", E.toString());
|
||||
}
|
||||
// if (Arrow) {
|
||||
// xml.printArg("arrow", "true");
|
||||
// } //plus nécessaire
|
||||
if (code_symbol > 0) {
|
||||
xml.printArg("code_symbol", "" + code_symbol);
|
||||
}
|
||||
super.printArgs(xml);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getLength() {
|
||||
return R;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getLength3D() {
|
||||
return R3D;
|
||||
}
|
||||
|
||||
public boolean is3D() {
|
||||
return Is3D;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean fixed() {
|
||||
return Fixed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fixed3D() {
|
||||
return Fixed3D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFixed(final boolean flag, final String s)
|
||||
throws ConstructionException {
|
||||
if (!flag || s.equals("")) {
|
||||
Fixed = false;
|
||||
E = null;
|
||||
} else {
|
||||
E = new Expression(s, getConstruction(), this);
|
||||
if (!E.isValid()) {
|
||||
throw new ConstructionException(E.getErrorText());
|
||||
}
|
||||
Fixed = true;
|
||||
}
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFixed3D(final boolean flag, final String s)
|
||||
throws ConstructionException {
|
||||
if (!flag || s.equals("")) {
|
||||
Fixed3D = false;
|
||||
E3D = null;
|
||||
} else {
|
||||
E3D = new Expression(s, getConstruction(), this);
|
||||
if (!E3D.isValid()) {
|
||||
throw new ConstructionException(E.getErrorText());
|
||||
}
|
||||
Fixed3D = true;
|
||||
}
|
||||
updateText();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void round() {
|
||||
try {
|
||||
setFixed(true, getDisplayValue());
|
||||
validate();
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Segment can be fixed in length.
|
||||
*/
|
||||
@Override
|
||||
public boolean canFix() {
|
||||
return P1.moveableBy(this) || P2.moveableBy(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(final double x, final double y) {
|
||||
final double a = (x - X1) * DX + (y - Y1) * DY;
|
||||
if (a < -1e-9 || a > R + 1e-9) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double project(final double x, final double y) {
|
||||
final double h = super.project(x, y);
|
||||
if (h < 0) {
|
||||
return 0;
|
||||
}
|
||||
if (h > R) {
|
||||
return R;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true, if equal.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final ConstructionObject o) {
|
||||
if (!(o instanceof SegmentObject) || !o.valid()) {
|
||||
return false;
|
||||
}
|
||||
final SegmentObject l = (SegmentObject) o;
|
||||
return (equals(X1, l.X1) && equals(X2, l.X2) && equals(Y1, l.Y1) && equals(
|
||||
Y2, l.Y2))
|
||||
|| (equals(X1, l.X2) && equals(Y1, l.Y2) && equals(X2, l.X1) && equals(
|
||||
Y2, l.Y1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isValidFix() {
|
||||
return E != null && E.isValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStringLength() {
|
||||
if (E != null) {
|
||||
return E.toString();
|
||||
} else {
|
||||
return "" + round(R);
|
||||
}
|
||||
}
|
||||
|
||||
public String getStringLength3D() {
|
||||
if (E3D != null) {
|
||||
return E3D.toString();
|
||||
} else {
|
||||
return "" + round(R3D);
|
||||
}
|
||||
}
|
||||
|
||||
public int getSegmentCode() {
|
||||
return code_symbol;
|
||||
}
|
||||
|
||||
public void setSegmentCode(final int i) {
|
||||
code_symbol = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue() throws ConstructionException {
|
||||
if (!Valid) {
|
||||
throw new InvalidException("exception.invalid");
|
||||
} else {
|
||||
if (!P1.is3D()||!P2.is3D()) return R;
|
||||
else return R3D;
|
||||
}
|
||||
}
|
||||
|
||||
public double getValue3D() throws ConstructionException {
|
||||
if (!Valid) {
|
||||
throw new InvalidException("exception.invalid");
|
||||
} else {
|
||||
return R3D;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
super.translate();
|
||||
try {
|
||||
setFixed(Fixed, E.toString());
|
||||
E.translate();
|
||||
} catch (final Exception e) {
|
||||
Fixed = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
if (!Fixed &&!Fixed3D) {
|
||||
return super.depending();
|
||||
} else {
|
||||
if (E!= null) {
|
||||
super.depending();
|
||||
final Enumeration e = E.getDepList().elements();
|
||||
while (e.hasMoreElements()) {
|
||||
DL.add((ConstructionObject) e.nextElement());
|
||||
}
|
||||
}
|
||||
if (E3D!=null) {
|
||||
final Enumeration f = E3D.getDepList().elements();
|
||||
while (f.hasMoreElements()) {
|
||||
DL.add((ConstructionObject) f.nextElement());
|
||||
}
|
||||
}
|
||||
return DL.elements();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setArrow(final boolean arrow) {
|
||||
Arrow = arrow;
|
||||
}
|
||||
|
||||
public boolean isArrow() {
|
||||
return Arrow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void project(final PointObject P) {
|
||||
final double h = project(P.getX(), P.getY());
|
||||
P.setXY(getX() + h * getDX(), getY() + h * getDY());
|
||||
P.setA(h / getLength());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void project(final PointObject P, final double alpha) {
|
||||
final double d = alpha * getLength();
|
||||
P.setXY(getX() + d * getDX(), getY() + d * getDY());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveable() {
|
||||
if (!Fixed && P1.moveable() && P2.moveable()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFixed(final boolean bool) {
|
||||
if (bool) {
|
||||
E = new Expression(this.getStringLength(), getConstruction(), this);
|
||||
}
|
||||
Fixed=bool;
|
||||
}
|
||||
}
|
||||
28
rene/zirkel/objects/SimulationObject.java
Normal file
28
rene/zirkel/objects/SimulationObject.java
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
|
||||
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;
|
||||
|
||||
public interface SimulationObject {
|
||||
public void setSimulationValue(double x);
|
||||
|
||||
public void resetSimulationValue();
|
||||
}
|
||||
386
rene/zirkel/objects/TextObject.java
Normal file
386
rene/zirkel/objects/TextObject.java
Normal file
|
|
@ -0,0 +1,386 @@
|
|||
/*
|
||||
|
||||
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: PointObject.java
|
||||
import java.awt.FontMetrics;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.StringReader;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
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;
|
||||
import rene.zirkel.expression.ExpressionColor;
|
||||
import rene.zirkel.expression.ExpressionString;
|
||||
import rene.zirkel.graphics.MyGraphics;
|
||||
import rene.zirkel.graphics.MainGraphics;
|
||||
|
||||
public class TextObject extends ConstructionObject implements MoveableObject {
|
||||
|
||||
protected double X, Y;
|
||||
Vector T;
|
||||
static Count N=new Count();
|
||||
double C, R, W, H;
|
||||
protected Expression EX, EY;
|
||||
protected boolean Fixed;
|
||||
protected boolean DoShow; // for replays
|
||||
|
||||
public TextObject(final Construction c, final double x, final double y) {
|
||||
super(c);
|
||||
X=x;
|
||||
Y=y;
|
||||
T=new Vector();
|
||||
setColor(ColorIndex, SpecialColor);
|
||||
Valid=true;
|
||||
setLines("<txt>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaults() {
|
||||
// setShowName(Global.getParameter("options.text.shownames",false));
|
||||
// setShowValue(Global.getParameter("options.text.showvalues",false));
|
||||
setShowName(true);
|
||||
setShowValue(true);
|
||||
setColor(Global.getParameter("options.text.color", 0), Global.getParameter("options.text.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.text.colortype", 0));
|
||||
setHidden(Cn.Hidden);
|
||||
setObtuse(Cn.Obtuse);
|
||||
setSolid(Cn.Solid);
|
||||
setLarge(Cn.LargeFont);
|
||||
setBold(Cn.BoldFont);
|
||||
setPartial(Cn.Partial);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetDefaults() {
|
||||
|
||||
setShowName(true);
|
||||
setShowValue(true);
|
||||
setColor(Global.getParameter("options.text.color", 0), Global.getParameter("options.text.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.text.colortype", 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int x, final int y, final ZirkelCanvas zc) {
|
||||
|
||||
if (!displays(zc)) {
|
||||
return false;
|
||||
}
|
||||
return C<=x&&R<=y&&x<=C+W&&y<=R+H;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Text";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getN() {
|
||||
return N.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
setText(getLines(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(final double x, final double y) {
|
||||
X=x;
|
||||
Y=y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(final MyGraphics g, final ZirkelCanvas zc) {
|
||||
C=zc.col(X);
|
||||
R=zc.row(Y);
|
||||
|
||||
// if (true) {
|
||||
// Enumeration e=T.elements();
|
||||
// String txt="";
|
||||
// while (e.hasMoreElements()) {
|
||||
// String s = ((ExpressionString) e.nextElement()).evaluate();
|
||||
// txt=txt+s+"coucou\n";
|
||||
// }
|
||||
// g.drawLaTeXString(txt,C,R);
|
||||
// return;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (mustHide(zc)) {
|
||||
return;
|
||||
}
|
||||
final boolean hidden=Hidden;
|
||||
if (DoShow) {
|
||||
Hidden=false;
|
||||
}
|
||||
g.setColor(this);
|
||||
setFont(g);
|
||||
if (DoShow) {
|
||||
Hidden=hidden;
|
||||
}
|
||||
FontMetrics fm=g.getFontMetrics();
|
||||
W=H=fm.getHeight();
|
||||
final Enumeration e=T.elements();
|
||||
double r=R;
|
||||
while (e.hasMoreElements()) {
|
||||
String s=((ExpressionString) e.nextElement()).evaluate();
|
||||
boolean bold=false, large=false;
|
||||
if (s.startsWith("***")) {
|
||||
s=s.substring(3);
|
||||
bold=large=true;
|
||||
} else if (s.startsWith("**")) {
|
||||
s=s.substring(2);
|
||||
large=true;
|
||||
} else if (s.startsWith("*")) {
|
||||
s=s.substring(1);
|
||||
bold=true;
|
||||
}
|
||||
if (isStrongSelected()) {
|
||||
((MainGraphics) g).drawMarkerRect(C, r, 10, 10);
|
||||
g.setColor(this);
|
||||
}
|
||||
g.setFont(large, bold);
|
||||
// r+=g.drawLaTeXString(s, C, r);
|
||||
|
||||
r += g.drawStringExtended(s, C, r);
|
||||
|
||||
W=Math.max(W, ((MainGraphics) g).getW());
|
||||
// W=Math.max(W, fm.stringWidth(s));
|
||||
|
||||
|
||||
}
|
||||
H=r-R;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mustHide(final ZirkelCanvas zc) {
|
||||
return super.mustHide(zc)&&!(Valid&&DoShow);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
Valid=true;
|
||||
if (Fixed&&EX!=null&&EX.isValid()) {
|
||||
try {
|
||||
X=EX.getValue();
|
||||
} catch (final Exception e) {
|
||||
Valid=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (Fixed&&EY!=null&&EY.isValid()) {
|
||||
try {
|
||||
Y=EY.getValue();
|
||||
} catch (final Exception e) {
|
||||
Valid=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLines() {
|
||||
String S="";
|
||||
final Enumeration e=T.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
final String s=((ExpressionString) e.nextElement()).toString();
|
||||
S=S+s;
|
||||
if (e.hasMoreElements()) {
|
||||
S=S+"\n";
|
||||
}
|
||||
}
|
||||
return S;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLines(String o) {
|
||||
if (o.equals("")) {
|
||||
o="<txt>";
|
||||
}
|
||||
final Vector w=new Vector();
|
||||
try {
|
||||
final BufferedReader in=new BufferedReader(new StringReader(o));
|
||||
while (true) {
|
||||
final String s=in.readLine();
|
||||
if (s==null) {
|
||||
break;
|
||||
}
|
||||
w.addElement(new ExpressionString(s, this));
|
||||
}
|
||||
in.close();
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
T=w;
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayValue() {
|
||||
return "("+roundDisplay(X)+","+roundDisplay(Y)+")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getX() {
|
||||
return X;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getY() {
|
||||
return Y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
if (Fixed&&EX!=null&&EX.isValid()) {
|
||||
xml.printArg("x", EX.toString());
|
||||
} else {
|
||||
xml.printArg("x", ""+X);
|
||||
}
|
||||
if (Fixed&&EY!=null&&EY.isValid()) {
|
||||
xml.printArg("y", EY.toString());
|
||||
} else {
|
||||
xml.printArg("y", ""+Y);
|
||||
}
|
||||
if (Fixed) {
|
||||
xml.printArg("fixed", "true");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean moveable() {
|
||||
return !Fixed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fixed() {
|
||||
return Fixed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFixed(final boolean flag) {
|
||||
Fixed=flag;
|
||||
if (!Fixed) {
|
||||
EX=EY=null;
|
||||
}
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFixed(final String x, final String y) {
|
||||
Fixed=true;
|
||||
EX=new Expression(x, getConstruction(), this);
|
||||
EY=new Expression(y, getConstruction(), this);
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEX() {
|
||||
if (EX!=null) {
|
||||
return EX.toString();
|
||||
} else {
|
||||
return ""+round(X);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEY() {
|
||||
if (EY!=null) {
|
||||
return EY.toString();
|
||||
} else {
|
||||
return ""+round(Y);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDoShow(final boolean flag) {
|
||||
DoShow=flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void snap(final ZirkelCanvas zc) {
|
||||
final double d=zc.getGridSize()/2;
|
||||
X=Math.round(X/d)*d;
|
||||
Y=Math.round(Y/d)*d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
if (Fixed) {
|
||||
try {
|
||||
setFixed(EX.toString(), EY.toString());
|
||||
EX.translate();
|
||||
EY.translate();
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
super.depending();
|
||||
final Enumeration e=T.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
((ExpressionString) e.nextElement()).addDep(this);
|
||||
}
|
||||
if (Fixed) {
|
||||
if (EX!=null) {
|
||||
EX.addDep(this);
|
||||
}
|
||||
if (EY!=null) {
|
||||
EY.addDep(this);
|
||||
}
|
||||
}
|
||||
return DL.elements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDisplayName() {
|
||||
return false;
|
||||
}
|
||||
double oldx, oldy, startx, starty;
|
||||
|
||||
public void startDrag(final double x, final double y) {
|
||||
oldx=X;
|
||||
oldy=Y;
|
||||
startx=x;
|
||||
starty=y;
|
||||
}
|
||||
|
||||
public void dragTo(final double x, final double y) {
|
||||
move(oldx+(x-startx), oldy+(y-starty));
|
||||
}
|
||||
|
||||
public double getOldX() {
|
||||
return oldx;
|
||||
}
|
||||
|
||||
public double getOldY() {
|
||||
return oldy;
|
||||
}
|
||||
}
|
||||
1273
rene/zirkel/objects/TrackObject.java
Normal file
1273
rene/zirkel/objects/TrackObject.java
Normal file
File diff suppressed because it is too large
Load diff
132
rene/zirkel/objects/TwoPointLineObject.java
Normal file
132
rene/zirkel/objects/TwoPointLineObject.java
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
|
||||
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: SegmentObject.java
|
||||
|
||||
import java.util.Enumeration;
|
||||
|
||||
import rene.zirkel.ZirkelCanvas;
|
||||
import rene.zirkel.construction.Construction;
|
||||
|
||||
public class TwoPointLineObject extends PrimitiveLineObject implements
|
||||
MoveableObject {
|
||||
protected PointObject P2, P1;
|
||||
double X2, Y2, R, R3D;
|
||||
|
||||
public TwoPointLineObject(final Construction c, final PointObject p1,
|
||||
final PointObject p2) {
|
||||
super(c);
|
||||
P1 = p1;
|
||||
P2 = p2;
|
||||
}
|
||||
|
||||
public void setP1P2(final PointObject p1, final PointObject p2) {
|
||||
P1 = p1;
|
||||
P2 = p2;
|
||||
}
|
||||
|
||||
public PointObject getP2() {
|
||||
return P2;
|
||||
}
|
||||
|
||||
public PointObject getP1() {
|
||||
return P1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration secondaryParams() {
|
||||
DL.reset();
|
||||
return depset(P1, P2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
super.depending();
|
||||
return depset(P1, P2);
|
||||
}
|
||||
|
||||
public double getLength() {
|
||||
return R;
|
||||
}
|
||||
|
||||
public double getLength3D() {
|
||||
return R3D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
P1 = (PointObject) P1.getTranslation();
|
||||
P2 = (PointObject) P2.getTranslation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(final PointObject p) {
|
||||
return P1 == p || P2 == p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void dragTo(final double x, final double y) {
|
||||
// System.out.println(getName()+" : dragTo !");
|
||||
P1.move(x1 + (x - x3), y1 + (y - y3));
|
||||
P2.move(x2 + (x - x3), y2 + (y - y3));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(final double x, final double y) {
|
||||
}
|
||||
|
||||
public boolean moveable() {
|
||||
if (P1.moveable() && P2.moveable())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
double x1, y1, x2, y2, x3, y3;
|
||||
|
||||
public void startDrag(final double x, final double y) {
|
||||
x1 = P1.getX();
|
||||
y1 = P1.getY();
|
||||
x2 = P2.getX();
|
||||
y2 = P2.getY();
|
||||
x3 = x;
|
||||
y3 = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void snap(final ZirkelCanvas zc) {
|
||||
if (moveable()) {
|
||||
P1.snap(zc);
|
||||
P2.snap(zc);
|
||||
}
|
||||
}
|
||||
|
||||
public double getOldX() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double getOldY() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
483
rene/zirkel/objects/UserFunctionObject.java
Normal file
483
rene/zirkel/objects/UserFunctionObject.java
Normal file
|
|
@ -0,0 +1,483 @@
|
|||
/*
|
||||
|
||||
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: Functionbject.java
|
||||
import java.awt.Checkbox;
|
||||
import java.awt.Color;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Frame;
|
||||
import java.awt.TextField;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.util.Enumeration;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import eric.JEricPanel;
|
||||
|
||||
import rene.dialogs.Warning;
|
||||
import rene.gui.Global;
|
||||
import rene.gui.IconBar;
|
||||
import rene.gui.MyLabel;
|
||||
import rene.gui.TextFieldAction;
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.gui.Global;
|
||||
import rene.zirkel.ZirkelCanvas;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.construction.ConstructionException;
|
||||
import rene.zirkel.construction.Count;
|
||||
import rene.zirkel.expression.Expression;
|
||||
import rene.zirkel.expression.InvalidException;
|
||||
import rene.zirkel.graphics.MyGraphics;
|
||||
import eric.bar.JProperties;
|
||||
import eric.bar.JPropertiesBar;
|
||||
import rene.zirkel.expression.ExpressionColor;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author Rene
|
||||
*
|
||||
* This class is for function of several variables. Those functions
|
||||
* cannot be drawn at all.
|
||||
*/
|
||||
public class UserFunctionObject extends ConstructionObject implements
|
||||
MoveableObject, DriverObject, Evaluator {
|
||||
static Count N = new Count();
|
||||
Expression EY = null;
|
||||
double X[] = { 0 };
|
||||
String Var[] = { "x" };
|
||||
protected double Xpos, Ypos;
|
||||
protected boolean Fixed;
|
||||
protected Expression EXpos, EYpos;
|
||||
String LASTE = "";
|
||||
|
||||
public UserFunctionObject(final Construction c) {
|
||||
super(c);
|
||||
validate();
|
||||
updateText();
|
||||
N.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaults() {
|
||||
setShowName(Global.getParameter("options.text.shownames", false));
|
||||
setShowValue(Global.getParameter("options.text.showvalues", false));
|
||||
setColor(Global.getParameter("options.text.color", 0), Global
|
||||
.getParameter("options.text.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.text.colortype", 0));
|
||||
setHidden(Cn.Hidden);
|
||||
setObtuse(Cn.Obtuse);
|
||||
setSolid(Cn.Solid);
|
||||
setLarge(Cn.LargeFont);
|
||||
setBold(Cn.BoldFont);
|
||||
setPartial(Cn.Partial);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetDefaults() {
|
||||
setShowName(Global.getParameter("options.text.shownames", false));
|
||||
setShowValue(Global.getParameter("options.text.showvalues", false));
|
||||
setColor(Global.getParameter("options.text.color", 0), Global
|
||||
.getParameter("options.text.pcolor", (ExpressionColor) null, this));
|
||||
setColorType(Global.getParameter("options.text.colortype", 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "Function";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getN() {
|
||||
return N.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
setText(getDisplayValue());
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return Valid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
if (EY != null) {
|
||||
Valid = EY.isValid();
|
||||
} else {
|
||||
Valid = false;
|
||||
}
|
||||
if (Fixed && EXpos != null && EXpos.isValid()) {
|
||||
try {
|
||||
Xpos = EXpos.getValue();
|
||||
} catch (final Exception e) {
|
||||
Valid = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (Fixed && EYpos != null && EYpos.isValid()) {
|
||||
try {
|
||||
Ypos = EYpos.getValue();
|
||||
} catch (final Exception e) {
|
||||
Valid = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setExpressions(final String t, final String ey) {
|
||||
final StringTokenizer tok = new StringTokenizer(t);
|
||||
Var = new String[tok.countTokens()];
|
||||
X = new double[tok.countTokens()];
|
||||
int i = 0;
|
||||
while (tok.hasMoreTokens()) {
|
||||
Var[i++] = tok.nextToken();
|
||||
}
|
||||
EY = new Expression(ey, getConstruction(), this, Var);
|
||||
validate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEY() {
|
||||
if (EY != null) {
|
||||
return EY.toString();
|
||||
} else {
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
|
||||
double C, R, W, H;
|
||||
|
||||
@Override
|
||||
public void paint(final MyGraphics g, final ZirkelCanvas zc) {
|
||||
if (!Valid || mustHide(zc)) {
|
||||
return;
|
||||
}
|
||||
final FontMetrics fm = g.getFontMetrics();
|
||||
H = fm.getHeight();
|
||||
C = zc.col(Xpos);
|
||||
R = zc.row(Ypos);
|
||||
g.setColor(this);
|
||||
setFont(g);
|
||||
final String s = AngleObject.translateToUnicode(getDisplayValue());
|
||||
g.drawString(s, C, R);
|
||||
R -= H;
|
||||
W = fm.stringWidth(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue() throws ConstructionException {
|
||||
if (!Valid) {
|
||||
throw new InvalidException("exception.invalid");
|
||||
}
|
||||
return X[0];
|
||||
}
|
||||
|
||||
public double getValue(final String var) throws ConstructionException {
|
||||
if (!Valid) {
|
||||
throw new InvalidException("exception.invalid");
|
||||
}
|
||||
for (int i = 0; i < Var.length; i++) {
|
||||
if (var.equals(Var[i])) {
|
||||
return X[i];
|
||||
}
|
||||
}
|
||||
return X[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayValue() {
|
||||
String s = "";
|
||||
if (showName()) {
|
||||
if (getAlias() != null) {
|
||||
s = getAlias() + " : ";
|
||||
}
|
||||
s = s + getName() + "(" + Var[0];
|
||||
for (int i = 1; i < Var.length; i++) {
|
||||
s = s + "," + Var[i];
|
||||
}
|
||||
s = s + ")";
|
||||
if (showValue()) {
|
||||
s = s + "=";
|
||||
}
|
||||
}
|
||||
if (showValue()) {
|
||||
s = s
|
||||
+ ((EY == null) ? "" : JProperties.Point_To_Comma(EY
|
||||
.toString(), Cn, true));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nearto(final int cc, final int rr, final ZirkelCanvas zc) {
|
||||
if (!displays(zc)) {
|
||||
return false;
|
||||
}
|
||||
return C <= cc && R <= rr && cc <= C + W && rr <= R + H;
|
||||
}
|
||||
|
||||
public boolean EditAborted;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
xml.printArg("f", EY.toString());
|
||||
if (Fixed && EXpos != null && EXpos.isValid()) {
|
||||
xml.printArg("x", EXpos.toString());
|
||||
} else {
|
||||
xml.printArg("x", "" + Xpos);
|
||||
}
|
||||
if (Fixed && EYpos != null && EYpos.isValid()) {
|
||||
xml.printArg("y", EYpos.toString());
|
||||
} else {
|
||||
xml.printArg("y", "" + Ypos);
|
||||
}
|
||||
if (Fixed) {
|
||||
xml.printArg("fixed", "true");
|
||||
}
|
||||
xml.printArg("var", getVar());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
try {
|
||||
EY = new Expression(EY.toString(), getConstruction(), this, Var);
|
||||
final ConstructionObject O = getTranslation();
|
||||
setTranslation(this);
|
||||
if (Fixed) {
|
||||
try {
|
||||
setFixed(EXpos.toString(), EYpos.toString());
|
||||
EXpos.translate();
|
||||
EYpos.translate();
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
}
|
||||
validate();
|
||||
setTranslation(O);
|
||||
} catch (final Exception e) {
|
||||
System.out.println();
|
||||
System.out.println(getName());
|
||||
System.out.println(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFixed(final boolean flag) {
|
||||
Fixed = flag;
|
||||
if (!Fixed) {
|
||||
EXpos = EYpos = null;
|
||||
}
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFixed(final String x, final String y) {
|
||||
Fixed = true;
|
||||
EXpos = new Expression(x, getConstruction(), this);
|
||||
EYpos = new Expression(y, getConstruction(), this);
|
||||
updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fixed() {
|
||||
return Fixed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEXpos() {
|
||||
if (EXpos != null) {
|
||||
return EXpos.toString();
|
||||
} else {
|
||||
return "" + round(Xpos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEYpos() {
|
||||
if (EYpos != null) {
|
||||
return EYpos.toString();
|
||||
} else {
|
||||
return "" + round(Ypos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onlynearto(final int x, final int y, final ZirkelCanvas zc) {
|
||||
return false;
|
||||
// return nearto(x,y,zc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final ConstructionObject o) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration depending() {
|
||||
DL.reset();
|
||||
addDepending(EY);
|
||||
if (Fixed) {
|
||||
addDepending(EXpos);
|
||||
addDepending(EYpos);
|
||||
}
|
||||
return DL.elements();
|
||||
}
|
||||
|
||||
public void addDepending(final Expression E) {
|
||||
if (E != null) {
|
||||
final Enumeration e = E.getDepList().elements();
|
||||
while (e.hasMoreElements()) {
|
||||
DL.add((ConstructionObject) e.nextElement());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUnit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public double evaluateF(final double x[]) throws ConstructionException {
|
||||
int n = x.length;
|
||||
if (n > X.length) {
|
||||
n = X.length;
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
X[i] = x[i];
|
||||
}
|
||||
for (int i = n; i < X.length; i++) {
|
||||
X[i] = 0;
|
||||
}
|
||||
try {
|
||||
return EY.getValue();
|
||||
} catch (final Exception e) {
|
||||
throw new ConstructionException("");
|
||||
}
|
||||
}
|
||||
|
||||
public double evaluateF(final double x) throws ConstructionException {
|
||||
X[0] = x;
|
||||
for (int i = 1; i < X.length; i++) {
|
||||
X[i] = 0;
|
||||
}
|
||||
try {
|
||||
return EY.getValue();
|
||||
} catch (final Exception e) {
|
||||
throw new ConstructionException("");
|
||||
}
|
||||
}
|
||||
|
||||
public double evaluateF(final double x, final double y)
|
||||
throws ConstructionException {
|
||||
X[0] = x;
|
||||
X[1] = y;
|
||||
for (int i = 2; i < X.length; i++) {
|
||||
X[i] = 0;
|
||||
}
|
||||
try {
|
||||
return EY.getValue();
|
||||
} catch (final Exception e) {
|
||||
throw new ConstructionException("");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean maybeTransparent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDisplayName() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFilledForSelect() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getVar() {
|
||||
String vars = Var[0];
|
||||
for (int i = 1; i < Var.length; i++) {
|
||||
vars = vars + " " + Var[i];
|
||||
}
|
||||
return vars;
|
||||
}
|
||||
|
||||
public void dragTo(final double x, final double y) {
|
||||
move(oldx + (x - startx), oldy + (y - starty));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(final double x, final double y) {
|
||||
Xpos = x;
|
||||
Ypos = y;
|
||||
}
|
||||
|
||||
double oldx, oldy, startx, starty;
|
||||
|
||||
public boolean moveable() {
|
||||
return !Fixed;
|
||||
}
|
||||
|
||||
public void startDrag(final double x, final double y) {
|
||||
oldx = Xpos;
|
||||
oldy = Ypos;
|
||||
startx = x;
|
||||
starty = y;
|
||||
}
|
||||
|
||||
public double getOldX() {
|
||||
return oldx;
|
||||
}
|
||||
|
||||
public double getOldY() {
|
||||
return oldy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getX() {
|
||||
return Xpos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getY() {
|
||||
return Ypos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDriverObject() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean somethingChanged() {
|
||||
return (!EY.toString().equals(LASTE));
|
||||
}
|
||||
|
||||
public void clearChanges() {
|
||||
LASTE = EY.toString();
|
||||
}
|
||||
}
|
||||
328
rene/zirkel/objects/VectorObject.java
Normal file
328
rene/zirkel/objects/VectorObject.java
Normal file
|
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package rene.zirkel.objects;
|
||||
|
||||
import eric.JZirkelCanvas;
|
||||
import rene.gui.Global;
|
||||
import rene.util.xml.XmlWriter;
|
||||
import rene.zirkel.construction.Construction;
|
||||
import rene.zirkel.construction.Count;
|
||||
import rene.zirkel.expression.Expression;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author PM
|
||||
*/
|
||||
public class VectorObject extends SegmentObject {
|
||||
private Expression EX = null;
|
||||
private Expression EY = null;
|
||||
private Expression EX3D = null;
|
||||
private Expression EY3D = null;
|
||||
private Expression EZ3D = null;
|
||||
//private double X3D = 0;
|
||||
//private double Y3D = 0;
|
||||
//private double Z3D = 0;
|
||||
static Count N = new Count();
|
||||
|
||||
public VectorObject(final Construction c, final PointObject p1, final PointObject p2) {
|
||||
super(c, p1, p2);
|
||||
Arrow = true;
|
||||
|
||||
// int n = Global.name("name.short.Vector").length();
|
||||
// String name = Name.substring(0, n)+"_"+Name.substring(n);
|
||||
// this.setAlias("$\\overrightarrow{"+name+"}");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Boolean is2DObject(){
|
||||
return !Is3D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isTellsSon(){
|
||||
return true;
|
||||
//the vector object, like William Tell's son, has an arrow over it
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setName() {
|
||||
Name=Global.name("name.short.Vector")+getN();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getN() {
|
||||
return N.next();
|
||||
}
|
||||
|
||||
public double getDeltaX(){
|
||||
return P2.getX()-P1.getX();
|
||||
}
|
||||
|
||||
public double getDeltaY(){
|
||||
return P2.getY()-P1.getY();
|
||||
}
|
||||
|
||||
public double getDeltaX3D(){
|
||||
return P2.getX3D()-P1.getX3D();
|
||||
}
|
||||
|
||||
public double getDeltaY3D(){
|
||||
return P2.getY3D()-P1.getY3D();
|
||||
}
|
||||
|
||||
public double getDeltaZ3D(){
|
||||
return P2.getZ3D()-P1.getZ3D();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fixedCoord(){
|
||||
boolean b = P2.getEX().equals("x("+P1.getName()+")"+"+"+getEX());
|
||||
b &= P2.getEY().equals("y("+P1.getName()+")"+"+"+getEY());
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fixedCoord3D(){
|
||||
boolean b = P2.getEX3D().equals("x3D("+P1.getName()+")"+"+"+getEX3D());
|
||||
b &= P2.getEY3D().equals("y3D("+P1.getName()+")"+"+"+getEY3D());
|
||||
b &= P2.getEZ3D().equals("z3D("+P1.getName()+")"+"+"+getEZ3D());
|
||||
return b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(double x, double y){
|
||||
P2.setColorType(THIN);
|
||||
//P2.setHidden(true);
|
||||
P2.move(P1.getX()+x, P1.getY()+y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move3D(double x, double y, double z){
|
||||
P2.setColorType(THIN);
|
||||
//P2.setHidden(true);
|
||||
P2.move3D(P1.getX3D()+x, P1.getY3D()+y, P1.getZ3D()+z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCDPDisplayValue(){
|
||||
return "("+Global.getCDPLocaleNumber(this.getDeltaX(), 2)+" "+(Global.getParameter("options.germanpoints", false)?"|":";")+Global.getCDPLocaleNumber(this.getDeltaY(), 2)+")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayValue() {
|
||||
/*
|
||||
String rep = "";
|
||||
if(!this.showName()) {
|
||||
rep += "$";
|
||||
}*/
|
||||
if (P1.is3D()&&P2.is3D()) return "\\left(\\begin{array}{r}"+Global.getLocaleNumber(getDeltaX3D(), "lengths")+"\\\\"+Global.getLocaleNumber(getDeltaY3D(), "lengths")+"\\\\"+Global.getLocaleNumber(getDeltaZ3D(), "lengths")+"\\end{array}\\right)";
|
||||
else return "\\left(\\begin{array}{r}"+Global.getLocaleNumber(getDeltaX(), "lengths")+"\\\\"+Global.getLocaleNumber(getDeltaY(), "lengths")+"\\end{array}\\right)";
|
||||
//return rep+"\\left(\\begin{array}{r}"+Global.getLocaleNumber(getDeltaX(), "lengths")+"\\\\"+Global.getLocaleNumber(getDeltaY(), "lengths")+"\\end{array}\\right)$";
|
||||
//return "("+Global.getLocaleNumber(getDeltaX(), "lengths")+(Global.getParameter("options.germanpoints", false)?"|":";")+Global.getLocaleNumber(getDeltaY(), "lengths")+")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateText() {
|
||||
if (!Fixed && !this.fixedCoord()) {
|
||||
setText(text2(Global.name("text.vector"), P1.getName(), P2.getName()));
|
||||
} else if (Fixed) {
|
||||
if (E == null) {
|
||||
setText(text3(Global.name("text.vector.fixed.length"), P1.getName(), P2.getName(), "" + round(R)));
|
||||
} else {
|
||||
setText(text3(Global.name("text.vector.fixed.length"), P1.getName(), P2.getName(), "\"" + E.toString() + "\""));
|
||||
}
|
||||
} else {
|
||||
setText(text3(Global.name("text.vector.fixed.coord"), P1.getName(), P2.getName(), "(" + round(this.getDeltaX())+" ; " + round(this.getDeltaY()) + ")"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFixed(final String x, final String y) {
|
||||
setEXY(x, y);
|
||||
P2.setFixed("x("+P1.getName()+")"+"+"+EX.toString(), "y("+P1.getName()+")"+"+"+EY.toString());
|
||||
P2.setColorType(THIN);
|
||||
P2.setBack(true);//modif proposée par Alain le 29/12/12 parce que je sais pas comment mettre un numéro de calque :-X
|
||||
updateText();
|
||||
JZirkelCanvas.getCurrentZC().repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFixed(boolean b){
|
||||
P2.setFixed(b);
|
||||
P2.setColorType(b?THIN:NORMAL);
|
||||
//P2.setHidden(b);
|
||||
updateText();
|
||||
JZirkelCanvas.getCurrentZC().repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFixed3D(boolean b){
|
||||
P2.setFixed3D(b);
|
||||
P2.setColorType(b?THIN:NORMAL);
|
||||
//P2.setHidden(b);
|
||||
updateText();
|
||||
JZirkelCanvas.getCurrentZC().repaint();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setFixed(final String x, final String y, final String z) {
|
||||
setEXYZ(x, y, z);
|
||||
P2.setFixed("x3D("+P1.getName()+")"+"+"+EX3D.toString(), "y3D("+P1.getName()+")"+"+"+EY3D.toString(), "z3D("+P1.getName()+")"+"+"+EZ3D.toString());
|
||||
P2.setColorType(THIN);
|
||||
P2.setBack(true);//modif proposée par Alain le 29/12/12 parce que je sais pas comment mettre un numéro de calque :-X
|
||||
updateText();
|
||||
JZirkelCanvas.getCurrentZC().repaint();
|
||||
}
|
||||
|
||||
public void setEXY(String x, String y){
|
||||
EX = new Expression(x, getConstruction(), this);
|
||||
EY = new Expression(y, getConstruction(), this);
|
||||
}
|
||||
|
||||
public void setEXYZ(String x3D, String y3D, String z3D){
|
||||
EX3D = new Expression(x3D, getConstruction(), this);
|
||||
EY3D = new Expression(y3D, getConstruction(), this);
|
||||
EZ3D = new Expression(z3D, getConstruction(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEX() {
|
||||
if (EX!=null) {
|
||||
return EX.toString();
|
||||
} else {
|
||||
return ""+round(this.getDeltaX());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEY() {
|
||||
if (EY!=null) {
|
||||
return EY.toString();
|
||||
} else {
|
||||
return ""+round(this.getDeltaY());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEX3D() {
|
||||
if (EX3D!=null) {
|
||||
return EX3D.toString();
|
||||
} else {
|
||||
return ""+round(this.getDeltaX3D());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEY3D() {
|
||||
if (EY3D!=null) {
|
||||
return EY3D.toString();
|
||||
} else {
|
||||
return ""+round(this.getDeltaY3D());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEZ3D() {
|
||||
if (EZ3D!=null) {
|
||||
return EZ3D.toString();
|
||||
} else {
|
||||
return ""+round(this.getDeltaZ3D());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printArgs(final XmlWriter xml) {
|
||||
xml.printArg("from", P1.getName());
|
||||
xml.printArg("to", P2.getName());
|
||||
if (Fixed && E != null) {
|
||||
xml.printArg("fixed", E.toString());
|
||||
}
|
||||
if(fixedCoord()){
|
||||
xml.printArg("x", EX.toString());
|
||||
xml.printArg("y", EY.toString());
|
||||
}
|
||||
if (Is3D) {
|
||||
xml.printArg("is3D", "true");
|
||||
|
||||
if (Fixed3D && E3D != null) {
|
||||
xml.printArg("fixed3D", E3D.toString());
|
||||
}
|
||||
|
||||
if(fixedCoord3D()){
|
||||
xml.printArg("x3D", EX3D.toString());
|
||||
xml.printArg("y3D", EY3D.toString());
|
||||
xml.printArg("z3D", EZ3D.toString());
|
||||
}
|
||||
}
|
||||
if (Fixed3D) {
|
||||
xml.printArg("fixed3D", "true");
|
||||
}
|
||||
xml.printArg("arrow", "true");
|
||||
if (code_symbol > 0) {
|
||||
xml.printArg("code_symbol", "" + code_symbol);
|
||||
}
|
||||
if (Partial) {
|
||||
xml.printArg("partial", "true");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveable() {
|
||||
if(P1.moveable()&&!is3D()){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructionObject copy(final double x, final double y) {
|
||||
VectorObject o=null;
|
||||
try {
|
||||
o=(VectorObject) clone();
|
||||
setTranslation(o);
|
||||
o.translateConditionals();
|
||||
o.translate();
|
||||
o.setName();
|
||||
o.updateText();
|
||||
o.setBreak(false);
|
||||
//o.setTarget(false);
|
||||
} catch (final Exception e) {}
|
||||
return o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate() {
|
||||
super.translate();
|
||||
if (Is3D) {
|
||||
try {
|
||||
setEXYZ(EX3D.toString(), EY3D.toString(), EZ3D.toString());
|
||||
EX3D.translate();
|
||||
EY3D.translate();
|
||||
EZ3D.translate();
|
||||
}
|
||||
catch (final Exception e) {}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
setEXY(EX.toString(), EY.toString());
|
||||
EX.translate();
|
||||
EY.translate();
|
||||
} catch (final Exception e) {
|
||||
//setFixed(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void setIs3D(boolean b) {
|
||||
Is3D=b;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue