diff --git a/android-app-core/src/main/java/org/solovyev/android/calculator/plot/AndroidCalculatorPlotter.java b/android-app-core/src/main/java/org/solovyev/android/calculator/plot/AndroidCalculatorPlotter.java index 69ee93a5..3bd15e5c 100644 --- a/android-app-core/src/main/java/org/solovyev/android/calculator/plot/AndroidCalculatorPlotter.java +++ b/android-app-core/src/main/java/org/solovyev/android/calculator/plot/AndroidCalculatorPlotter.java @@ -169,4 +169,9 @@ public class AndroidCalculatorPlotter implements CalculatorPlotter, SharedPrefer setPlotImag(CalculatorPreferences.Graph.plotImag.getPreference(preferences)); } } + + @Override + public void setPlotData(boolean plot3d, @NotNull PlotBoundaries plotBoundaries) { + plotter.setPlotData(plot3d, plotBoundaries); + } } diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/AbstractCalculatorPlotFragment.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/AbstractCalculatorPlotFragment.java index 3672377c..952d483d 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/plot/AbstractCalculatorPlotFragment.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/plot/AbstractCalculatorPlotFragment.java @@ -216,7 +216,13 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment @Override public void onClick(@NotNull MenuItem data, @NotNull Context context) { - Locator.getInstance().getPlotter().setPlot3d(true); + final PlotBoundaries plotBoundaries = getPlotBoundaries(); + + if (plotBoundaries != null) { + Locator.getInstance().getPlotter().setPlotData(true, plotBoundaries); + } else { + Locator.getInstance().getPlotter().setPlot3d(true); + } } }; menuItems.add(plot3dMenuItem); @@ -231,7 +237,13 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment @Override public void onClick(@NotNull MenuItem data, @NotNull Context context) { - Locator.getInstance().getPlotter().setPlot3d(false); + final PlotBoundaries plotBoundaries = getPlotBoundaries(); + + if (plotBoundaries != null) { + Locator.getInstance().getPlotter().setPlotData(false, plotBoundaries); + } else { + Locator.getInstance().getPlotter().setPlot3d(false); + } } }; menuItems.add(plot2dMenuItem); diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorGraph2dView.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorGraph2dView.java index f9f8fbe3..4ea6cce5 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorGraph2dView.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorGraph2dView.java @@ -598,6 +598,8 @@ public class CalculatorGraph2dView extends View implements GraphView { public void onTouchZoomDown(float x1, float y1, float x2, float y2) { zoomTracker.start(dimensions.getGWidth(), dimensions.getGHeight(), x1, y1, x2, y2); + lastTouchXPxs = NO_TOUCH; + lastTouchYPxs = NO_TOUCH; } public void onTouchZoomMove(float x1, float y1, float x2, float y2) { @@ -612,16 +614,11 @@ public class CalculatorGraph2dView extends View implements GraphView { } private void scroll(float deltaX, float deltaY) { - final float scale = dimensions.getGWidth() / dimensions.getVWidthPxs(); - float dx = deltaX * scale; - float dy = deltaY * scale; - final float adx = Math.abs(dx); - final float ady = Math.abs(dy); - if (adx < ady / 3) { - dx = 0; - } else if (ady < adx / 3) { - dy = 0; - } + final float xScale = dimensions.getXGraphToViewScale(); + final float yScale = dimensions.getYGraphToViewScale(); + + float dx = deltaX * xScale; + float dy = deltaY * yScale; dimensions.increaseXY(dx, dy); } diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorGraph3dView.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorGraph3dView.java index 67f00582..d6c0efb1 100755 --- a/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorGraph3dView.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorGraph3dView.java @@ -167,7 +167,7 @@ public class CalculatorGraph3dView extends GLView implements GraphView { @Override public void setXRange(float xMin, float xMax) { - dimensions.setXRange(PlotBoundaries.DEFAULT_MIN_NUMBER, PlotBoundaries.DEFAULT_MAX_NUMBER); + dimensions.setRanges(1, 1, 1, 1); zoomLevel = 1; dirty = true; diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/Graph2dDimensions.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/Graph2dDimensions.java index c40d2a20..2c3d11fc 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/plot/Graph2dDimensions.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/plot/Graph2dDimensions.java @@ -165,15 +165,30 @@ public class Graph2dDimensions { */ public void setXRange(float xMin, float xMax) { - this.gWidth = xMax - xMin; - this.x0 = xMin + gWidth / 2; + setXRange0(xMin, xMax); this.graphView.invalidateGraphs(); } + private void setXRange0(float xMin, float xMax) { + this.gWidth = xMax - xMin; + this.x0 = xMin + gWidth / 2; + } + public void setYRange(float yMin, float yMax) { + setYRange0(yMin, yMax); + + this.graphView.invalidateGraphs(); + } + + private void setYRange0(float yMin, float yMax) { this.gHeight = yMax - yMin; this.y0 = yMin + gHeight / 2; + } + + public void setRanges(float xMin, float xMax, float yMin, float yMax) { + setXRange0(xMin, xMax); + setYRange0(yMin, yMax); this.graphView.invalidateGraphs(); } diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/ZoomTracker.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/ZoomTracker.java index 5076ab85..225aa8df 100755 --- a/android-app/src/main/java/org/solovyev/android/calculator/plot/ZoomTracker.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/plot/ZoomTracker.java @@ -1,56 +1,58 @@ package org.solovyev.android.calculator.plot; class ZoomTracker { - private float sx1, sy1, sx2, sy2; - private float initialDist; + + private static final float EPS = 1.5f; + private static final float MIN_DISTANCE = distance(0f, 50f); + public static final String TAG = "ZoomTracker"; + + private float initialXDistance; + private float initialYDistance; private float initialXValue; private float initialYValue; float xValue; float yValue; - float moveX, moveY; - void start(float xValue, float yValue, float x1, float y1, float x2, float y2) { - sx1 = x1; - sy1 = y1; - sx2 = x2; - sy2 = y2; - initialDist = distance(x1, y1, x2, y2); + void start(float xValue, float yValue, + float x1, float y1, + float x2, float y2) { + + initialXDistance = distance(x1, x2); + initialYDistance = distance(y1, y2); + initialXValue = xValue; initialYValue = yValue; + + this.xValue = xValue; + this.yValue = yValue; } boolean update(float x1, float y1, float x2, float y2) { - final float LIMIT = 1.5f; - if (Math.abs(x1 - sx1) < LIMIT && Math.abs(y1 - sy1) < LIMIT && - Math.abs(x2 - sx2) < LIMIT && Math.abs(y2 - sy2) < LIMIT) { - return false; + boolean result = false; + + if (initialXDistance > MIN_DISTANCE) { + final float xDistance = distance(x1, x2); + if (xDistance > EPS) { + xValue = initialXDistance / xDistance * initialXValue; + result = true; + } } - moveX = common(x1, sx1, x2, sx2); - moveY = common(y1, sy1, y2, sy2); - float dist = distance(x1, y1, x2, y2); - xValue = initialDist / dist * initialXValue; - yValue = initialDist / dist * initialYValue; - sx1 = x1; - sx2 = x2; - sy1 = y1; - sy2 = y2; - return true; + + if (initialYDistance > MIN_DISTANCE) { + final float yDistance = distance(y1, y2); + if (yDistance > EPS) { + yValue = initialYDistance / yDistance * initialYValue; + result = true; + } + } + + return result; } - private static float distance(float x1, float y1, float x2, float y2) { - final float dx = x1-x2; - final float dy = y1-y2; - // return (float) Math.sqrt(dx*dx+dy*dy); - return Math.max(dx*dx, dy*dy); - } - - private float common(float x1, float sx1, float x2, float sx2) { - float dx1 = x1 - sx1; - float dx2 = x2 - sx2; - return (dx1 < 0 && dx2 < 0) ? Math.max(dx1, dx2) : - (dx1 > 0 && dx2 > 0) ? Math.min(dx1, dx2): - 0; + private static float distance(float x1, float x2) { + final float dx = x1 - x2; + return dx * dx; } } diff --git a/core/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotter.java b/core/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotter.java index 338c778a..5a49f645 100644 --- a/core/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotter.java +++ b/core/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotter.java @@ -58,6 +58,7 @@ public interface CalculatorPlotter { boolean isPlotPossibleFor(@NotNull Generic expression); void setPlot3d(boolean plot3d); + void setPlotData(boolean plot3d, @NotNull PlotBoundaries plotBoundaries); void removeAllUnpinned(); diff --git a/core/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotterImpl.java b/core/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotterImpl.java index 1d1222cf..8a787e2f 100644 --- a/core/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotterImpl.java +++ b/core/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotterImpl.java @@ -372,6 +372,15 @@ public class CalculatorPlotterImpl implements CalculatorPlotter { } } + @Override + public void setPlotData(boolean plot3d, @NotNull PlotBoundaries plotBoundaries) { + if (this.plot3d != plot3d || this.plotBoundaries.equals(plotBoundaries)) { + this.plot3d = plot3d; + this.plotBoundaries = plotBoundaries; + firePlotDataChangedEvent(); + } + } + private void firePlotDataChangedEvent() { plotData = new PlotData(getVisibleFunctions(), plot3d, plotBoundaries); calculator.fireCalculatorEvent(CalculatorEventType.plot_data_changed, plotData);