package org.wheelmap.android.tango.mode; import org.rajawali3d.Object3D; import org.rajawali3d.math.vector.Vector3; import org.wheelmap.android.tango.mode.operations.CreateObjectsOperation; import org.wheelmap.android.tango.mode.operations.OperationsModeRenderer; import java.util.ArrayList; import java.util.List; import java.util.Locale; public abstract class MeasureSlopeAngleModeRenderer extends OperationsModeRenderer { private static final boolean SHOW_ANGLE_IN_PERCENTAGE = true; private List<Object3D> pointObjects = new ArrayList<>(); @Override public void onClickedAt(final float[] transform) { if (isOperationRunning()) { return; } addOperation(new CreateObjectsOperation() { @Override public void execute(Manipulator m) { if (isReady()) { return; } Object3D createdPoint = getObjectFactory().createMeasurePoint(); Object3dUtils.setObjectPose(createdPoint, transform); pointObjects.add(createdPoint); m.addObject(createdPoint); int size = pointObjects.size(); if (size > 1) { String text; if (SHOW_ANGLE_IN_PERCENTAGE) { text = String.format(Locale.getDefault(), "%.1f%%", getAnglePercentage()); } else { text = String.format(Locale.getDefault(), "%.1f\u00B0", getAngleDegree()); } getObjectFactory().measureLineBetween(m, pointObjects.get(size - 1).getPosition(), pointObjects.get(size - 2).getPosition(), text); } } @Override public void undo(Manipulator manipulator) { super.undo(manipulator); pointObjects.removeAll(getCreatedObjects()); } }); } @Override public boolean isReady() { return pointObjects.size() >= 2; } @Override public void clear() { super.clear(); pointObjects.clear(); } /** * calculates the angle of the line between the z surface */ public double getAngleDegree() { if (pointObjects.size() < 2) { return 0; } Vector3 one = pointObjects.get(0).getPosition(); Vector3 two = pointObjects.get(1).getPosition(); Vector3 u = one.clone().subtract(two); // normal to z surface Vector3 n = new Vector3(0, 1, 0); double top = n.clone().multiply(u).normalize(); double bottom = n.clone().normalize() * u.clone().normalize(); return Math.toDegrees(Math.asin(top/bottom)); } public double getAnglePercentage() { double angleDegree = getAngleDegree(); double angleRadians = Math.toRadians(angleDegree); return Math.tan(angleRadians) * 100; } }