/*
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.
*/
/*
* AlgoAnglePoints.java
*
* Created on 30. August 2001, 21:37
*/
package org.geogebra.common.kernel.algos;
import org.geogebra.common.kernel.Construction;
import org.geogebra.common.kernel.Kernel;
import org.geogebra.common.kernel.geos.GeoPoint;
import org.geogebra.common.kernel.kernelND.GeoDirectionND;
import org.geogebra.common.kernel.kernelND.GeoElementND;
import org.geogebra.common.kernel.kernelND.GeoPointND;
/**
*
* @author Markus
*/
public class AlgoAnglePoints extends AlgoAnglePointsND {
public AlgoAnglePoints(Construction cons, String label, GeoPointND A,
GeoPointND B, GeoPointND C) {
this(cons, label, A, B, C, null);
}
public AlgoAnglePoints(Construction cons, String label, GeoPointND A,
GeoPointND B, GeoPointND C, GeoDirectionND orientation) {
this(cons, A, B, C, orientation);
angle.setLabel(label);
}
AlgoAnglePoints(Construction cons, AlgoAnglePolygon algoAnglePoly,
GeoPointND A, GeoPointND B, GeoPointND C) {
this(cons, A, B, C, null);
this.algoAnglePoly = algoAnglePoly;
}
public AlgoAnglePoints(Construction cons, GeoPointND A, GeoPointND B,
GeoPointND C) {
this(cons, A, B, C, null);
}
public AlgoAnglePoints(Construction cons, GeoPointND A, GeoPointND B,
GeoPointND C, GeoDirectionND orientation) {
super(cons);
setInput(A, B, C, orientation);
setInputOutput(); // for AlgoElement
// compute angle
compute();
}
/**
* used as a helper algo (for AlgoAnglePolygon)
*
* @param cons
* construction
*/
protected AlgoAnglePoints(Construction cons) {
super(cons);
}
public AlgoAnglePoints(GeoPointND A, GeoPointND B, GeoPointND C) {
super(A.toGeoElement().cons, false);
this.leg1N = A;
this.vertexN = B;
this.leg2N = C;
}
@Override
public AlgoAnglePoints copy() {
return new AlgoAnglePoints(leg1N.copy(), vertexN.copy(), leg2N.copy());
}
// calc angle between vectors A-B and C-B
// angle in range [0, pi]
@Override
public void compute() {
GeoPoint A = (GeoPoint) leg1N;
GeoPoint B = (GeoPoint) vertexN;
GeoPoint C = (GeoPoint) leg2N;
if (!A.isFinite() || !B.isFinite() || !C.isFinite()) {
angle.setUndefined(); // undefined
return;
}
// get vectors v=BA and w=BC
bx = B.inhomX;
by = B.inhomY;
vx = A.inhomX - bx;
vy = A.inhomY - by;
wx = C.inhomX - bx;
wy = C.inhomY - by;
if (Kernel.isZero(vx) && Kernel.isZero(vy)
|| Kernel.isZero(wx) && Kernel.isZero(wy)) {
angle.setUndefined();
return;
}
// |v| * |w| * sin(alpha) = det(v, w)
// cos(alpha) = v . w / (|v| * |w|)
// tan(alpha) = sin(alpha) / cos(alpha)
// => tan(alpha) = det(v, w) / v . w
double det = vx * wy - vy * wx;
double prod = vx * wx + vy * wy;
double value = Math.atan2(det, prod);
angle.setValue(value);
}
// ///////////////////////////////
// TRICKS FOR XOY PLANE
// ///////////////////////////////
@Override
protected int getInputLengthForXML() {
return getInputLengthForXMLMayNeedXOYPlane();
}
@Override
protected int getInputLengthForCommandDescription() {
return getInputLengthForCommandDescriptionMayNeedXOYPlane();
}
@Override
public GeoElementND getInput(int i) {
return getInputMaybeXOYPlane(i);
}
}