/** * @param point point to rotate * @param pointCoords coordinates of this point * @param projectCoords coordinates of the projected point on bottom face * @param o coordinates of the origin of the rotation line * @param vs direction of the rotation line * @param f value of the cursor used in the rotation * @param fd direction of the bottom face * @param dist distance between point and projected point * @param test value (XOR) */ protected void rotate( GeoPoint3D point, Coords pointCoords, Coords projectCoords, Coords o, Coords vs, double f, Coords fd, double dist, boolean test) { Coords v2 = projectCoords.sub(o); double d2 = pointCoords.distLine(o, vs); double angle; if (Kernel.isEqual(dist, d2)) { angle = Math.PI / 2; } else { angle = Math.asin(dist / d2); } if (test ^ (v2.crossProduct(vs).dotproduct(fd) < 0)) { // top point is // inside bottom // face angle = Math.PI - angle; } point.rotate(f * angle, o, vs); }
@Override public boolean hit(Hitting hitting) { if (waitForReset) { // prevent NPE return false; } if (getGeoElement().getAlphaValue() < EuclidianController.MIN_VISIBLE_ALPHA_VALUE) { return false; } GeoPolygon poly = (GeoPolygon) getGeoElement(); if (poly.getCoordSys() == null) { App.debug("" + poly); return false; } // project hitting origin on polygon plane if (globalCoords == null) { globalCoords = new Coords(4); inPlaneCoords = new Coords(4); } if (hitting.isSphere()) { hitting.origin.projectPlane(poly.getCoordSys().getMatrixOrthonormal(), globalCoords); if (hittingPointForOutline == null) { hittingPointForOutline = new GeoPoint3D(poly.getConstruction()); hittingPointForOutline.setWillingCoordsUndefined(); hittingPointForOutline.setWillingDirectionUndefined(); } // try outline hittingPointForOutline.setCoords(globalCoords); poly.pointChanged(hittingPointForOutline); Coords p3d = hittingPointForOutline.getInhomCoordsInD3(); if (project == null) { project = Coords.createInhomCoorsInD3(); } double d = p3d.distance(hitting.origin); double scale = getView3D().getScale(); if (d * scale <= poly.getLineThickness() + hitting.getThreshold()) { setZPick(-d, -d); setPickingType(PickingType.POINT_OR_CURVE); return true; } // try inside hittingPointForOutline.setCoords(globalCoords); hittingPointForOutline.setRegion(poly); poly.pointChangedForRegion(hittingPointForOutline); p3d = hittingPointForOutline.getInhomCoordsInD3(); d = p3d.distance(hitting.origin); if (d * scale <= hitting.getThreshold()) { setZPick(-d, -d); setPickingType(PickingType.SURFACE); return true; } } else { hitting.origin.projectPlaneThruVIfPossible( poly.getCoordSys().getMatrixOrthonormal(), hitting.direction, globalCoords, inPlaneCoords); if (!hitting.isInsideClipping(globalCoords)) { return false; } boolean ret = false; // check if hitting projection hits the polygon if (poly.isInRegion(inPlaneCoords.getX(), inPlaneCoords.getY())) { double parameterOnHitting = inPlaneCoords.getZ(); // TODO use // other for // non-parallel // projection // : // -hitting.origin.distance(project[0]); setZPick(parameterOnHitting, parameterOnHitting); setPickingType(PickingType.SURFACE); ret = true; } // check if hitting is on path if (!poly.wasInitLabelsCalled()) { if (hittingPointForOutline == null) { hittingPointForOutline = new GeoPoint3D(poly.getConstruction()); } hittingPointForOutline.setCoords(globalCoords); poly.pointChanged(hittingPointForOutline); Coords p3d = hittingPointForOutline.getInhomCoordsInD3(); if (hitting.isInsideClipping(p3d)) { if (project == null) { project = Coords.createInhomCoorsInD3(); } p3d.projectLine( hitting.origin, hitting.direction, project, parameters); // check distance to hitting line double d = p3d.distance(project); double scale = getView3D().getScale(); if (d * scale <= poly.getLineThickness() + hitting.getThreshold()) { double z = -parameters[0]; double dz = poly.getLineThickness() / scale; setZPick(z + dz, z - dz); setPickingType(PickingType.POINT_OR_CURVE); return true; } } } return ret; } return false; }