[apps/graph] Move nextIntersectionFrom method from controller to model

and take into account the function domain in the intersection
computation
This commit is contained in:
Émilie Feral
2019-09-09 10:22:44 +02:00
parent fdaec27ad9
commit 7b8973f020
3 changed files with 26 additions and 5 deletions

View File

@@ -42,15 +42,12 @@ void IntersectionGraphController::reloadBannerView() {
Poincare::Coordinate2D<double> IntersectionGraphController::computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) {
// TODO The following three lines should be factored.
constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1;
char unknownX[bufferSize];
Poincare::SerializationHelper::CodePoint(unknownX, bufferSize, UCodePointUnknownX);
Poincare::Coordinate2D<double> result = Poincare::Coordinate2D<double>(NAN, NAN);
for (int i = 0; i < functionStore()->numberOfActiveFunctions(); i++) {
Ion::Storage::Record record = functionStore()->activeRecordAtIndex(i);
if (record != m_record) {
Poincare::Expression e = functionStore()->modelForRecord(record)->expressionReduced(context);
Poincare::Coordinate2D<double> intersection = Shared::PoincareHelpers::NextIntersection(functionStore()->modelForRecord(m_record)->expressionReduced(context), unknownX, start, step, max, context, e);
CartesianFunction f = *(functionStore()->modelForRecord(record));
Poincare::Coordinate2D<double> intersection = functionStore()->modelForRecord(m_record)->nextIntersectionFrom(start, step, max, context, &f);
if ((std::isnan(result.x1()) || std::fabs(intersection.x1()-start) < std::fabs(result.x1()-start)) && !std::isnan(intersection.x1())) {
m_intersectedRecord = record;
result = (std::isnan(result.x1()) || std::fabs(intersection.x1()-start) < std::fabs(result.x1()-start)) ? intersection : result;

View File

@@ -16,6 +16,9 @@ using namespace Poincare;
namespace Shared {
static inline double maxDouble(double x, double y) { return x > y ? x : y; }
static inline double minDouble(double x, double y) { return x < y ? x : y; }
void CartesianFunction::DefaultName(char buffer[], size_t bufferSize) {
constexpr int k_maxNumberOfDefaultLetterNames = 4;
static constexpr const char k_defaultLetterNames[k_maxNumberOfDefaultLetterNames] = {
@@ -271,6 +274,24 @@ Coordinate2D<T> CartesianFunction::templatedApproximateAtParameter(T t, Poincare
PoincareHelpers::ApproximateWithValueForSymbol(e.childAtIndex(1), unknown, t, context));
}
Coordinate2D<double> CartesianFunction::nextIntersectionFrom(double start, double step, double max, Poincare::Context * context, CartesianFunction * f) const {
assert(plotType() == PlotType::Cartesian);
constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1;
char unknownX[bufferSize];
SerializationHelper::CodePoint(unknownX, bufferSize, UCodePointUnknownX);
double domainMin = maxDouble(tMin(), f->tMin());
double domainMax = minDouble(tMax(), f->tMax());
if (step > 0.0f) {
start = maxDouble(start, domainMin);
max = minDouble(max, domainMax);
} else {
start = minDouble(start, domainMax);
max = maxDouble(max, domainMin);
}
return PoincareHelpers::NextIntersection(expressionReduced(context), unknownX, start, step, max, context, f->expressionReduced(context));
}
template Coordinate2D<float> CartesianFunction::templatedApproximateAtParameter<float>(float, Poincare::Context *) const;
template Coordinate2D<double> CartesianFunction::templatedApproximateAtParameter<double>(double, Poincare::Context *) const;

View File

@@ -5,6 +5,7 @@
#include "function.h"
#include "range_1D.h"
#include <poincare/symbol.h>
#include <poincare/coordinate_2D.h>
namespace Shared {
@@ -56,6 +57,8 @@ public:
void setTMax(float tMax);
float rangeStep() const override { return plotType() == PlotType::Cartesian ? NAN : (tMax() - tMin())/k_polarParamRangeSearchNumberOfPoints; }
// Cartesian calculation
Poincare::Coordinate2D<double> nextIntersectionFrom(double start, double step, double max, Poincare::Context * context, CartesianFunction * f) const;
private:
constexpr static float k_polarParamRangeSearchNumberOfPoints = 100.0f; // This is ad hoc, no special justification
template <typename T> Poincare::Coordinate2D<T> privateEvaluateXYAtParameter(T t, Poincare::Context * context) const;