Skip to content

Commit

Permalink
#124 3D plot fails whenever one interval is used twice: fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
mkulesh committed Sep 29, 2022
1 parent 2890dd3 commit 0116d28
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 13 deletions.
63 changes: 54 additions & 9 deletions app/src/main/java/com/mkulesh/micromath/plots/PlotContour.java
Original file line number Diff line number Diff line change
Expand Up @@ -653,11 +653,12 @@ public String[] getLabels()
void calculate(CalculaterTask thread) throws CancelException
{
final CalculatedValue calcVal = new CalculatedValue();
ArrayList<Equation> linkedIntervals = getDirectIntervals();
if (linkedIntervals.size() != 2)
final ArrayList<Equation> linkedIntervals = getDirectIntervals();
if (linkedIntervals.size() != 1 && linkedIntervals.size() != 2)
{
return;
}
final boolean isFunction1D = linkedIntervals.size() == 1;

// prepare axis and minimum and maximum values
minMaxValues[FunctionIf.X][FunctionIf.MIN] = Double.NEGATIVE_INFINITY;
Expand All @@ -672,7 +673,8 @@ void calculate(CalculaterTask thread) throws CancelException
calcVal.processRealTerm(thread, xMax);
minMaxValues[FunctionIf.X][FunctionIf.MAX] = calcVal.getReal();
}
xValues = linkedIntervals.get(0).fillBoundedInterval(xValues, minMaxValues[FunctionIf.X]);
final Equation xValuesEq = linkedIntervals.get(0);
xValues = xValuesEq.fillBoundedInterval(xValues, minMaxValues[FunctionIf.X]);
if (xValues == null)
{
return;
Expand All @@ -690,15 +692,16 @@ void calculate(CalculaterTask thread) throws CancelException
calcVal.processRealTerm(thread, yMax);
minMaxValues[FunctionIf.Y][FunctionIf.MAX] = calcVal.getReal();
}
yValues = linkedIntervals.get(1).fillBoundedInterval(yValues, minMaxValues[FunctionIf.Y]);
final Equation yValuesEq = isFunction1D ? linkedIntervals.get(0) : linkedIntervals.get(1);
yValues = yValuesEq.fillBoundedInterval(yValues, minMaxValues[FunctionIf.Y]);
if (yValues == null)
{
return;
}

// labels
labels[FunctionIf.X] = linkedIntervals.get(0).getName();
labels[FunctionIf.Y] = linkedIntervals.get(1).getName();
labels[FunctionIf.X] = xValuesEq.getName();
labels[FunctionIf.Y] = yValuesEq.getName();
labels[FunctionIf.Z] = "";

// calculate z values
Expand All @@ -708,14 +711,57 @@ void calculate(CalculaterTask thread) throws CancelException
argValues[1][0] = new CalculatedValue();
}
zValues = new double[xValues.length][yValues.length];
if (isFunction1D)
{
calculate1D(xValuesEq, thread);
}
else
{
calculate2D(xValuesEq, yValuesEq, thread);
}
updateEqualBorders(minMaxValues[FunctionIf.Z]);
}

private void calculate1D(Equation xValuesEq, CalculaterTask thread) throws CancelException
{
final CalculatedValue calcVal = new CalculatedValue();
for (int i = 0; i < xValues.length; i++)
{
for (int j = 0; j < yValues.length; j++)
{
zValues[i][j] = Double.NaN;
}

argValues[0][0].setValue(xValues[i]);
xValuesEq.setArgumentValues(argValues[0]);
calcVal.processRealTerm(thread, functionTerm);
final double zVal = calcVal.getReal();
zValues[i][i] = zVal;
if (i == 0)
{
minMaxValues[FunctionIf.Z][FunctionIf.MIN] = minMaxValues[FunctionIf.Z][FunctionIf.MAX] = zVal;
}
else
{
minMaxValues[FunctionIf.Z][FunctionIf.MIN] = Math.min(
minMaxValues[FunctionIf.Z][FunctionIf.MIN], zVal);
minMaxValues[FunctionIf.Z][FunctionIf.MAX] = Math.max(
minMaxValues[FunctionIf.Z][FunctionIf.MAX], zVal);
}
}
}

private void calculate2D(Equation xValuesEq, Equation yValuesEq, CalculaterTask thread) throws CancelException
{
final CalculatedValue calcVal = new CalculatedValue();
for (int i = 0; i < xValues.length; i++)
{
argValues[0][0].setValue(xValues[i]);
linkedIntervals.get(0).setArgumentValues(argValues[0]);
xValuesEq.setArgumentValues(argValues[0]);
for (int j = 0; j < yValues.length; j++)
{
argValues[1][0].setValue(yValues[j]);
linkedIntervals.get(1).setArgumentValues(argValues[1]);
yValuesEq.setArgumentValues(argValues[1]);
calcVal.processRealTerm(thread, functionTerm);
final double zVal = calcVal.getReal();
zValues[i][j] = zVal;
Expand All @@ -732,7 +778,6 @@ void calculate(CalculaterTask thread) throws CancelException
}
}
}
updateEqualBorders(minMaxValues[FunctionIf.Z]);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;

Expand Down Expand Up @@ -121,7 +122,9 @@ protected void drawContent(Canvas c, FunctionIf f)
// z
if (colorMapView != null)
{
p.setColor(colorMapView.getPaletteColor(zVal[i][j], f.getMinMaxValues(FunctionIf.Z), 255));
final int color = Double.isNaN(zVal[i][j]) ? Color.TRANSPARENT :
colorMapView.getPaletteColor(zVal[i][j], f.getMinMaxValues(FunctionIf.Z), 255);
p.setColor(color);
}

// draw
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ public void renderSurface(FunctionIf function)
{
final double y = function.getYValues()[j];
double v = function.getZValues()[i][j];
if (Double.isNaN(v))
{
v = get1dValue(function.getZValues(), i, j);
}
if (Double.isInfinite(v))
{
v = Double.NaN;
Expand All @@ -197,6 +201,19 @@ public void renderSurface(FunctionIf function)
function.getMinMaxValues(FunctionIf.Z)[FunctionIf.MAX]);
}

private double get1dValue(final double[][] zValues, int i, int j)
{
if (i > 0 && !Double.isNaN(zValues[i - 1][j]))
{
return zValues[i - 1][j];
}
if (j > 0 && !Double.isNaN(zValues[i][j - 1]))
{
return zValues[i][j - 1];
}
return Double.NaN;
}

public boolean isRendered()
{
return vertex != null;
Expand Down Expand Up @@ -384,14 +401,13 @@ private void drawBoundingBox(Canvas canvas)
*/
private void drawBoxGridsLabels(Canvas canvas)
{
boolean x_left = false, y_left = false;
int i;

factor_x = factor_y = 1;
projector.project(p1, 0, 0, -10);
poly_x[0] = p1.x;
projector.project(p1, 10.5f, 0, -10);
y_left = p1.x > poly_x[0];
boolean y_left = p1.x > poly_x[0];
i = p1.y;
projector.project(p1, -10.5f, 0, -10);
if (p1.y > i)
Expand All @@ -400,7 +416,7 @@ private void drawBoxGridsLabels(Canvas canvas)
y_left = p1.x > poly_x[0];
}
projector.project(p1, 0, 10.5f, -10);
x_left = p1.x > poly_x[0];
boolean x_left = p1.x > poly_x[0];
i = p1.y;
projector.project(p1, 0, -10.5f, -10);
if (p1.y > i)
Expand Down

0 comments on commit 0116d28

Please sign in to comment.