/*
GeoGebra - Dynamic Mathematics for Everyone
http://www.geogebra.org
This file is part of GeoGebra.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation.
*/
package org.geogebra.common.geogebra3D.kernel3D.geos;
import org.geogebra.common.geogebra3D.kernel3D.MyPoint3D;
import org.geogebra.common.kernel.Construction;
import org.geogebra.common.kernel.MyPoint;
import org.geogebra.common.kernel.PathParameter;
import org.geogebra.common.kernel.SegmentType;
import org.geogebra.common.kernel.Matrix.Coords;
import org.geogebra.common.kernel.arithmetic.ValueType;
import org.geogebra.common.kernel.geos.GeoLocusND;
import org.geogebra.common.kernel.kernelND.GeoPointND;
import org.geogebra.common.kernel.kernelND.GeoSegmentND;
/**
* Locus of points
*
* @author Markus
*/
public class GeoLocus3D extends GeoLocusND<MyPoint3D> {
/**
* Creates new locus
*
* @param c
* construction
*/
public GeoLocus3D(Construction c) {
super(c);
}
@Override
protected GeoLocus3D newGeoLocus() {
return new GeoLocus3D(cons);
}
/**
* Adds a new point (x,y,z) to the end of the point list of this locus.
*
* @param x
* x-coord
* @param y
* y-coord
* @param z
* z-coord
* @param lineTo
* true to draw a line to (x,y,z); false to only move to (x,y,z)
*/
public void insertPoint(double x, double y, double z, boolean lineTo) {
myPointList.add(new MyPoint3D(x, y, z, lineTo ? SegmentType.LINE_TO
: SegmentType.MOVE_TO));
}
@Override
public boolean isGeoElement3D() {
return true;
}
@Override
public boolean hasFillType() {
return false;
}
@Override
public void pointChanged(GeoPointND P) {
Coords coords = P.getInhomCoordsInD3();
setChangingPoint(P);
// this updates closestPointParameter and closestPointIndex
MyPoint closestPoint = getClosestPoint();
PathParameter pp = P.getPathParameter();
// Application.debug(pp.t);
if (closestPoint != null) {
coords.setX(closestPoint.x);// (1 - closestPointParameter) *
// locusPoint.x +
// closestPointParameter * locusPoint2.x;
coords.setY(closestPoint.y);// (1 - closestPointParameter) *
// locusPoint.y +
// closestPointParameter * locusPoint2.y;
coords.setZ(closestPoint.getZ());
coords.setW(1.0);
pp.t = closestPointIndex + closestPointParameter;
}
P.setCoords(coords, false);
P.updateCoords();
}
@Override
protected GeoSegmentND newGeoSegment() {
GeoSegment3D segment = new GeoSegment3D(cons);
/*
* GeoPoint p1 = new GeoPoint(cons); GeoPoint p2 = new GeoPoint(cons);
* segment.setStartPoint(p1); segment.setEndPoint(p2);
*/
return segment;
}
private GeoPointND changingPoint;
private Coords changingCoords;
@Override
protected void setChangingPoint(GeoPointND P) {
changingPoint = P;
changingCoords = P.getInhomCoordsInD3();
}
@Override
protected double changingPointDistance(GeoSegmentND segment) {
GeoSegment3D seg = (GeoSegment3D) segment;
double t = seg.getParamOnLine(changingPoint);
if (t < 0) {
t = 0;
} else if (t > 1) {
t = 1;
}
Coords project = seg.getPoint(t);
Coords coords = changingCoords;
if (changingPoint.isGeoElement3D()) {
if (((GeoPoint3D) changingPoint).hasWillingCoords()) {
coords = ((GeoPoint3D) changingPoint).getWillingCoords();
if (((GeoPoint3D) changingPoint).hasWillingDirection()) {
return project.distLine(coords,
((GeoPoint3D) changingPoint).getWillingDirection());
}
}
}
return coords.distance(project);
}
@Override
protected double getChangingPointParameter(GeoSegmentND segment) {
return ((GeoSegment3D) segment).getParamOnLine(changingPoint);
}
@Override
final public HitType getLastHitType() {
return HitType.ON_BOUNDARY;
}
@Override
public ValueType getValueType() {
return ValueType.PARAMETRIC3D;
}
}