/* 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.algos; import org.geogebra.common.geogebra3D.kernel3D.geos.GeoPoint3D; import org.geogebra.common.kernel.Construction; import org.geogebra.common.kernel.Kernel; import org.geogebra.common.kernel.Matrix.CoordMatrix; import org.geogebra.common.kernel.Matrix.Coords; import org.geogebra.common.kernel.kernelND.AlgoIntersectND; import org.geogebra.common.kernel.kernelND.GeoPointND; public abstract class AlgoIntersect3D extends AlgoIntersectND { public AlgoIntersect3D(Construction c) { super(c); } /** * Avoids two intersection points at same position. This is only done as * long as the second intersection point doesn't have a label yet. */ @Override protected void avoidDoubleTangentPoint() { GeoPoint3D[] points = getIntersectionPoints(); if (!points[1].isLabelSet() && points[0].isEqual(points[1])) { points[1].setUndefined(); } } /** * Returns the index in output[] of the intersection point that is closest * to the coordinates (xRW, yRW) TODO: move to an interface */ int getClosestPointIndex(double xRW, double yRW, CoordMatrix mat) { GeoPoint3D[] P = getIntersectionPoints(); double x, y, lengthSqr, mindist = Double.POSITIVE_INFINITY; // Application.debug("\nxRW="+xRW+"\nyRW="+yRW+"\nmatrix=\n"+mat); int minIndex = 0; for (int i = 0; i < P.length; i++) { Coords toScreenCoords; if (mat == null) { toScreenCoords = P[i].getInhomCoords(); } else { toScreenCoords = mat.mul(P[i].getCoords().getCoordsLast1()) .getInhomCoords(); } // Application.debug("\nScreen coords of point "+i+" // is:\n"+toScreenCoords); x = (toScreenCoords.getX() - xRW); y = (toScreenCoords.getY() - yRW); // comment: the z dimension is the "height", which will not be used // here. lengthSqr = x * x + y * y; if (lengthSqr < mindist) { mindist = lengthSqr; minIndex = i; } } return minIndex; } @Override public abstract GeoPoint3D[] getIntersectionPoints(); @Override protected abstract GeoPoint3D[] getLastDefinedIntersectionPoints(); int getClosestPointIndex(GeoPointND refPoint) { Coords refInhom = refPoint.getInhomCoordsInD3(); GeoPoint3D[] P = getIntersectionPoints(); double x, y, z, lengthSqr, mindist = Double.POSITIVE_INFINITY; int minIndex = 0; for (int i = 0; i < P.length; i++) { Coords PInhom = P[i].getInhomCoordsInD3(); x = (PInhom.getX() - refInhom.getX()); y = (PInhom.getY() - refInhom.getY()); z = (PInhom.getZ() - refInhom.getZ()); lengthSqr = x * x + y * y + z * z; // if two distances are equal, smaller index gets priority if (Kernel.isGreater(mindist, lengthSqr)) { mindist = lengthSqr; minIndex = i; } } return minIndex; } // TODO: organize better according to types: GeoVec, GeoVec4D, GeoVec3D, // Coords @Override protected void setCoords(GeoPointND destination, GeoPointND source) { ((GeoPoint3D) destination).setCoords(((GeoPoint3D) source).getCoords()); } @Override public abstract void compute(); @Override public abstract void initForNearToRelationship(); }