/* 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. */ /* * AlgoAngleLines.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.geogebra3D.kernel3D.geos.GeoPlane3D; import org.geogebra.common.kernel.Construction; import org.geogebra.common.kernel.StringTemplate; import org.geogebra.common.kernel.Matrix.CoordMatrix4x4; import org.geogebra.common.kernel.Matrix.Coords; import org.geogebra.common.kernel.algos.AlgoAngle; import org.geogebra.common.kernel.algos.DrawInformationAlgo; import org.geogebra.common.kernel.geos.GeoAngle; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.kernelND.GeoLineND; /** * * @author mathieu */ public class AlgoAngleLinePlane extends AlgoAngle implements DrawInformationAlgo { private GeoLineND g; // input private GeoPlane3D p; // input private GeoAngle angle; // output /** * Creates new unlabeled angle between line and plane * * @param cons * construction * @param g * line * @param p * plane */ AlgoAngleLinePlane(Construction cons, GeoLineND g, GeoPlane3D p) { super(cons); this.g = g; this.p = p; angle = newGeoAngle(cons); setInputOutput(); // for AlgoElement // compute angle compute(); } @Override final protected GeoAngle newGeoAngle(Construction cons1) { GeoAngle ret = new GeoAngle3D(cons1); ret.setDrawable(true); return ret; } private AlgoAngleLinePlane(GeoLineND g, GeoPlane3D p) { super(((GeoElement) g).getConstruction(), false); this.g = g; this.p = p; } /** * Creates new labeled angle between line and plane * * @param cons * construction * @param label * angle label * @param g * line * @param p * plane */ public AlgoAngleLinePlane(Construction cons, String label, GeoLineND g, GeoPlane3D p) { this(cons, g, p); angle.setLabel(label); } @Override public AlgoAngleLinePlane copy() { return new AlgoAngleLinePlane(g.copy(), p.copy()); } // for AlgoElement @Override protected void setInputOutput() { input = new GeoElement[2]; input[0] = (GeoElement) g; input[1] = p; setOutputLength(1); setOutput(0, angle); setDependencies(); // done by AlgoElement } /** * Returns the resulting angle * * @return resulting angle */ public GeoAngle getAngle() { return angle; } @Override final public String toString(StringTemplate tpl) { // Michael Borcherds 2008-03-30 // simplified to allow better Chinese translation return getLoc().getPlain("AngleBetweenAB", g.getLabel(tpl), p.getLabel(tpl)); } private Coords vn, o, v1, v2, tmpCoords; @Override protected void initCoords() { o = new Coords(4); v1 = new Coords(4); vn = new Coords(4); tmpCoords = new Coords(3); } @Override public final void compute() { // line origin and direction Coords o2 = g.getStartInhomCoords(); v2 = g.getDirectionInD3(); // plane matrix CoordMatrix4x4 pMat = p.getCoordSys().getMatrixOrthonormal(); // project line origin on the plane o2.projectPlaneThruV(pMat, v2, o); if (!o.isDefined()) { // line parallel to plane getAngle().setValue(0); return; } // project line direction on the plane Coords vx = pMat.getVx(); Coords vy = pMat.getVy(); v1.setAdd3(v1.setMul3(vx, v2.dotproduct(vx)), tmpCoords.setMul3(vy, v2.dotproduct(vy))); if (v1.isZero()) { // line orthogonal to plane getAngle().setValue(Math.PI / 2); v1.set3(vx); vn.setMul3(vy, -1); return; } 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)); vn.setCrossProduct(v2, v1); vn.normalize(); } @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(v2); if (!drawable.inView(v1v)) { return false; } Coords v2v = drawable.getCoordsInView(v1); 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] = v2; drawCoords[2] = v1; return true; } }