/* 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.geogebra3D.kernel3D.algos; import org.geogebra.common.euclidian.draw.DrawAngle; import org.geogebra.common.geogebra3D.kernel3D.geos.GeoAngle3D; import org.geogebra.common.kernel.Construction; import org.geogebra.common.kernel.Kernel; import org.geogebra.common.kernel.Matrix.CoordMatrixUtil; import org.geogebra.common.kernel.Matrix.Coords; import org.geogebra.common.kernel.algos.AlgoAngleLinesND; import org.geogebra.common.kernel.geos.GeoAngle; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.kernelND.GeoDirectionND; import org.geogebra.common.kernel.kernelND.GeoLineND; /** * * @author mathieu */ public class AlgoAngleLines3D extends AlgoAngleLinesND { protected Coords vn; private Coords o; private Coords v1; private Coords v2; AlgoAngleLines3D(Construction cons, String label, GeoLineND g, GeoLineND h, GeoDirectionND orientation) { super(cons, label, g, h, orientation); } AlgoAngleLines3D(Construction cons, String label, GeoLineND g, GeoLineND h) { this(cons, label, g, h, null); } @Override protected GeoAngle newGeoAngle(Construction cons1) { GeoAngle ret = new GeoAngle3D(cons1); ret.setDrawable(true); return ret; } @Override public void compute() { if (!getg().isDefined() || !geth().isDefined()) { getAngle().setUndefined(); return; } // lines origins and directions Coords o1 = getg().getStartInhomCoords(); v1 = getg().getDirectionInD3(); Coords o2 = geth().getStartInhomCoords(); v2 = geth().getDirectionInD3(); // normal vector vn = v1.crossProduct4(v2); if (!vn.isDefined() || vn.isZero()) { // parallel lines // check if lines are opposite rays if (!((GeoElement) getg()).isGeoRay() || !((GeoElement) geth()).isGeoRay() || Kernel.isGreaterEqual(v1.dotproduct(v2), 0)) { getAngle().setValue(0); o = Coords.UNDEFINED; // for drawing return; } getAngle().setValue(Math.PI); if (o1.equalsForKernel(o2)) { // opposite rays o = o1.copyVector(); v1.completeOrthonormal(vn); } else { o = Coords.UNDEFINED; // for drawing return; } } else { // non parallel lines // nearest points Coords[] points = CoordMatrixUtil.nearestPointsFromTwoLines(o1, v1, o2, v2); if (!points[0].equalsForKernel(points[1])) { // lines are not // coplanar getAngle().setUndefined(); return; } o = points[0]; vn.normalize(); } v1.calcNorm(); double l1 = v1.getNorm(); v2.calcNorm(); double l2 = v2.getNorm(); double c = v1.dotproduct(v2) / (l1 * l2); // cosinus of the angle getAngle().setValue(AlgoAnglePoints3D.acos(c)); } @Override public boolean updateDrawInfo(double[] m, double[] firstVec, DrawAngle drawable) { if (drawable == null) { // TODO : this is a pgf / asymptote / pstricks // call return false; } if (!o.isDefined()) { return false; } Coords ov = drawable.getCoordsInView(o); if (!drawable.inView(ov)) { return false; } m[0] = ov.get()[0]; m[1] = ov.get()[1]; Coords v1v = drawable.getCoordsInView(v1); if (!drawable.inView(v1v)) { return false; } Coords v2v = drawable.getCoordsInView(v2); if (!drawable.inView(v2v)) { return false; } firstVec[0] = v1v.get()[0]; firstVec[1] = v1v.get()[1]; return true; } @Override public Coords getVn() { return vn; } @Override public boolean getCoordsInD3(Coords[] drawCoords) { if (!o.isDefined()) { return false; } drawCoords[0] = o; drawCoords[1] = v1; drawCoords[2] = v2; return true; } private AlgoAngleLines3D(GeoLineND g, GeoLineND h) { super(g, h); } @Override public AlgoAngleLines3D copy() { return new AlgoAngleLines3D(g.copy(), h.copy()); } }