mirror of
https://github.com/gwm17/implot.git
synced 2024-11-26 20:28:50 -05:00
constrain values <= 0 to DBL_MIN for log axes, fix div by zero
This commit is contained in:
parent
0cafcd0011
commit
e9469cf347
40
implot.cpp
40
implot.cpp
|
@ -507,34 +507,36 @@ void PullLinkedAxis(ImPlotAxis& axis) {
|
|||
|
||||
void UpdateTransformCache() {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
ImPlotPlot& plot = *gp.CurrentPlot;
|
||||
// get pixels for transforms
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
gp.PixelRange[i] = ImRect(ImHasFlag(gp.CurrentPlot->XAxis.Flags, ImPlotAxisFlags_Invert) ? gp.CurrentPlot->PlotRect.Max.x : gp.CurrentPlot->PlotRect.Min.x,
|
||||
ImHasFlag(gp.CurrentPlot->YAxis[i].Flags, ImPlotAxisFlags_Invert) ? gp.CurrentPlot->PlotRect.Min.y : gp.CurrentPlot->PlotRect.Max.y,
|
||||
ImHasFlag(gp.CurrentPlot->XAxis.Flags, ImPlotAxisFlags_Invert) ? gp.CurrentPlot->PlotRect.Min.x : gp.CurrentPlot->PlotRect.Max.x,
|
||||
ImHasFlag(gp.CurrentPlot->YAxis[i].Flags, ImPlotAxisFlags_Invert) ? gp.CurrentPlot->PlotRect.Max.y : gp.CurrentPlot->PlotRect.Min.y);
|
||||
gp.My[i] = (gp.PixelRange[i].Max.y - gp.PixelRange[i].Min.y) / gp.CurrentPlot->YAxis[i].Range.Size();
|
||||
gp.PixelRange[i] = ImRect(plot.XAxis.IsInverted() ? plot.PlotRect.Max.x : plot.PlotRect.Min.x,
|
||||
plot.YAxis[i].IsInverted() ? plot.PlotRect.Min.y : plot.PlotRect.Max.y,
|
||||
plot.XAxis.IsInverted() ? plot.PlotRect.Min.x : plot.PlotRect.Max.x,
|
||||
plot.YAxis[i].IsInverted() ? plot.PlotRect.Max.y : plot.PlotRect.Min.y);
|
||||
gp.My[i] = (gp.PixelRange[i].Max.y - gp.PixelRange[i].Min.y) / plot.YAxis[i].Range.Size();
|
||||
}
|
||||
gp.LogDenX = ImLog10(gp.CurrentPlot->XAxis.Range.Max / gp.CurrentPlot->XAxis.Range.Min);
|
||||
gp.LogDenX = plot.XAxis.IsLog() ? ImLog10(plot.XAxis.Range.Max / plot.XAxis.Range.Min) : 0;
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++)
|
||||
gp.LogDenY[i] = ImLog10(gp.CurrentPlot->YAxis[i].Range.Max / gp.CurrentPlot->YAxis[i].Range.Min);
|
||||
gp.Mx = (gp.PixelRange[0].Max.x - gp.PixelRange[0].Min.x) / gp.CurrentPlot->XAxis.Range.Size();
|
||||
gp.LogDenY[i] = plot.YAxis[i].IsLog() ? ImLog10(plot.YAxis[i].Range.Max / plot.YAxis[i].Range.Min) : 0;
|
||||
gp.Mx = (gp.PixelRange[0].Max.x - gp.PixelRange[0].Min.x) / plot.XAxis.Range.Size();
|
||||
}
|
||||
|
||||
ImPlotPoint PixelsToPlot(float x, float y, ImPlotYAxis y_axis_in) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
ImPlotPlot& plot = *gp.CurrentPlot;
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "PixelsToPlot() needs to be called between BeginPlot() and EndPlot()!");
|
||||
const ImPlotYAxis y_axis = y_axis_in >= 0 ? y_axis_in : gp.CurrentPlot->CurrentYAxis;
|
||||
const ImPlotYAxis y_axis = y_axis_in >= 0 ? y_axis_in : plot.CurrentYAxis;
|
||||
ImPlotPoint plt;
|
||||
plt.x = (x - gp.PixelRange[y_axis].Min.x) / gp.Mx + gp.CurrentPlot->XAxis.Range.Min;
|
||||
plt.y = (y - gp.PixelRange[y_axis].Min.y) / gp.My[y_axis] + gp.CurrentPlot->YAxis[y_axis].Range.Min;
|
||||
if (ImHasFlag(gp.CurrentPlot->XAxis.Flags, ImPlotAxisFlags_LogScale)) {
|
||||
double t = (plt.x - gp.CurrentPlot->XAxis.Range.Min) / gp.CurrentPlot->XAxis.Range.Size();
|
||||
plt.x = ImPow(10, t * gp.LogDenX) * gp.CurrentPlot->XAxis.Range.Min;
|
||||
plt.x = (x - gp.PixelRange[y_axis].Min.x) / gp.Mx + plot.XAxis.Range.Min;
|
||||
plt.y = (y - gp.PixelRange[y_axis].Min.y) / gp.My[y_axis] + plot.YAxis[y_axis].Range.Min;
|
||||
if (ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_LogScale)) {
|
||||
double t = (plt.x - plot.XAxis.Range.Min) / plot.XAxis.Range.Size();
|
||||
plt.x = ImPow(10, t * gp.LogDenX) * plot.XAxis.Range.Min;
|
||||
}
|
||||
if (ImHasFlag(gp.CurrentPlot->YAxis[y_axis].Flags, ImPlotAxisFlags_LogScale)) {
|
||||
double t = (plt.y - gp.CurrentPlot->YAxis[y_axis].Range.Min) / gp.CurrentPlot->YAxis[y_axis].Range.Size();
|
||||
plt.y = ImPow(10, t * gp.LogDenY[y_axis]) * gp.CurrentPlot->YAxis[y_axis].Range.Min;
|
||||
if (ImHasFlag(plot.YAxis[y_axis].Flags, ImPlotAxisFlags_LogScale)) {
|
||||
double t = (plt.y - plot.YAxis[y_axis].Range.Min) / plot.YAxis[y_axis].Range.Size();
|
||||
plt.y = ImPow(10, t * gp.LogDenY[y_axis]) * plot.YAxis[y_axis].Range.Min;
|
||||
}
|
||||
return plt;
|
||||
}
|
||||
|
@ -543,17 +545,18 @@ ImPlotPoint PixelsToPlot(const ImVec2& pix, ImPlotYAxis y_axis) {
|
|||
return PixelsToPlot(pix.x, pix.y, y_axis);
|
||||
}
|
||||
|
||||
// This function is convenient but should not be used to process a high volume of points. Use the Transformer structs below instead.
|
||||
ImVec2 PlotToPixels(double x, double y, ImPlotYAxis y_axis_in) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "PlotToPixels() needs to be called between BeginPlot() and EndPlot()!");
|
||||
const ImPlotYAxis y_axis = y_axis_in >= 0 ? y_axis_in : gp.CurrentPlot->CurrentYAxis;
|
||||
ImVec2 pix;
|
||||
if (ImHasFlag(gp.CurrentPlot->XAxis.Flags, ImPlotAxisFlags_LogScale)) {
|
||||
x = x <= 0.0 ? IMPLOT_LOG_ZERO : x;
|
||||
double t = ImLog10(x / gp.CurrentPlot->XAxis.Range.Min) / gp.LogDenX;
|
||||
x = ImLerp(gp.CurrentPlot->XAxis.Range.Min, gp.CurrentPlot->XAxis.Range.Max, (float)t);
|
||||
}
|
||||
if (ImHasFlag(gp.CurrentPlot->YAxis[y_axis].Flags, ImPlotAxisFlags_LogScale)) {
|
||||
y = y <= 0.0 ? IMPLOT_LOG_ZERO : y;
|
||||
double t = ImLog10(y / gp.CurrentPlot->YAxis[y_axis].Range.Min) / gp.LogDenY[y_axis];
|
||||
y = ImLerp(gp.CurrentPlot->YAxis[y_axis].Range.Min, gp.CurrentPlot->YAxis[y_axis].Range.Max, (float)t);
|
||||
}
|
||||
|
@ -562,7 +565,6 @@ ImVec2 PlotToPixels(double x, double y, ImPlotYAxis y_axis_in) {
|
|||
return pix;
|
||||
}
|
||||
|
||||
// This function is convenient but should not be used to process a high volume of points. Use the Transformer structs below instead.
|
||||
ImVec2 PlotToPixels(const ImPlotPoint& plt, ImPlotYAxis y_axis) {
|
||||
return PlotToPixels(plt.x, plt.y, y_axis);
|
||||
}
|
||||
|
|
|
@ -59,6 +59,8 @@
|
|||
#define IMPLOT_MAX_TIME 32503680000
|
||||
// Default label format for axis labels
|
||||
#define IMPLOT_LABEL_FMT "%g"
|
||||
// Plot values less than or equal to 0 will be replaced with this on log scale axes
|
||||
#define IMPLOT_LOG_ZERO DBL_MIN
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Macros
|
||||
|
@ -666,11 +668,11 @@ struct ImPlotAxis
|
|||
void Constrain() {
|
||||
Range.Min = ImConstrainNan(ImConstrainInf(Range.Min));
|
||||
Range.Max = ImConstrainNan(ImConstrainInf(Range.Max));
|
||||
if (ImHasFlag(Flags, ImPlotAxisFlags_LogScale)) {
|
||||
if (IsLog()) {
|
||||
Range.Min = ImConstrainLog(Range.Min);
|
||||
Range.Max = ImConstrainLog(Range.Max);
|
||||
}
|
||||
if (ImHasFlag(Flags, ImPlotAxisFlags_Time)) {
|
||||
if (IsTime()) {
|
||||
Range.Min = ImConstrainTime(Range.Min);
|
||||
Range.Max = ImConstrainTime(Range.Max);
|
||||
}
|
||||
|
|
|
@ -435,8 +435,9 @@ struct TransformerLogLin {
|
|||
TransformerLogLin() : YAxis(GetCurrentYAxis()) {}
|
||||
inline ImVec2 operator()(const ImPlotPoint& plt) const {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
double t = ImLog10(plt.x / gp.CurrentPlot->XAxis.Range.Min) / gp.LogDenX;
|
||||
double x = ImLerp(gp.CurrentPlot->XAxis.Range.Min, gp.CurrentPlot->XAxis.Range.Max, (float)t);
|
||||
double x = plt.x <= 0.0 ? IMPLOT_LOG_ZERO : plt.x;
|
||||
double t = ImLog10(x / gp.CurrentPlot->XAxis.Range.Min) / gp.LogDenX;
|
||||
x = ImLerp(gp.CurrentPlot->XAxis.Range.Min, gp.CurrentPlot->XAxis.Range.Max, (float)t);
|
||||
return ImVec2( (float)(gp.PixelRange[YAxis].Min.x + gp.Mx * (x - gp.CurrentPlot->XAxis.Range.Min)),
|
||||
(float)(gp.PixelRange[YAxis].Min.y + gp.My[YAxis] * (plt.y - gp.CurrentPlot->YAxis[YAxis].Range.Min)) );
|
||||
}
|
||||
|
@ -448,8 +449,9 @@ struct TransformerLinLog {
|
|||
TransformerLinLog() : YAxis(GetCurrentYAxis()) {}
|
||||
inline ImVec2 operator()(const ImPlotPoint& plt) const {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
double t = ImLog10(plt.y / gp.CurrentPlot->YAxis[YAxis].Range.Min) / gp.LogDenY[YAxis];
|
||||
double y = ImLerp(gp.CurrentPlot->YAxis[YAxis].Range.Min, gp.CurrentPlot->YAxis[YAxis].Range.Max, (float)t);
|
||||
double y = plt.y <= 0.0 ? IMPLOT_LOG_ZERO : plt.y;
|
||||
double t = ImLog10(y / gp.CurrentPlot->YAxis[YAxis].Range.Min) / gp.LogDenY[YAxis];
|
||||
y = ImLerp(gp.CurrentPlot->YAxis[YAxis].Range.Min, gp.CurrentPlot->YAxis[YAxis].Range.Max, (float)t);
|
||||
return ImVec2( (float)(gp.PixelRange[YAxis].Min.x + gp.Mx * (plt.x - gp.CurrentPlot->XAxis.Range.Min)),
|
||||
(float)(gp.PixelRange[YAxis].Min.y + gp.My[YAxis] * (y - gp.CurrentPlot->YAxis[YAxis].Range.Min)) );
|
||||
}
|
||||
|
@ -461,10 +463,12 @@ struct TransformerLogLog {
|
|||
TransformerLogLog() : YAxis(GetCurrentYAxis()) {}
|
||||
inline ImVec2 operator()(const ImPlotPoint& plt) const {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
double t = ImLog10(plt.x / gp.CurrentPlot->XAxis.Range.Min) / gp.LogDenX;
|
||||
double x = ImLerp(gp.CurrentPlot->XAxis.Range.Min, gp.CurrentPlot->XAxis.Range.Max, (float)t);
|
||||
t = ImLog10(plt.y / gp.CurrentPlot->YAxis[YAxis].Range.Min) / gp.LogDenY[YAxis];
|
||||
double y = ImLerp(gp.CurrentPlot->YAxis[YAxis].Range.Min, gp.CurrentPlot->YAxis[YAxis].Range.Max, (float)t);
|
||||
double x = plt.x <= 0.0 ? IMPLOT_LOG_ZERO : plt.x;
|
||||
double y = plt.y <= 0.0 ? IMPLOT_LOG_ZERO : plt.y;
|
||||
double t = ImLog10(x / gp.CurrentPlot->XAxis.Range.Min) / gp.LogDenX;
|
||||
x = ImLerp(gp.CurrentPlot->XAxis.Range.Min, gp.CurrentPlot->XAxis.Range.Max, (float)t);
|
||||
t = ImLog10(y / gp.CurrentPlot->YAxis[YAxis].Range.Min) / gp.LogDenY[YAxis];
|
||||
y = ImLerp(gp.CurrentPlot->YAxis[YAxis].Range.Min, gp.CurrentPlot->YAxis[YAxis].Range.Max, (float)t);
|
||||
return ImVec2( (float)(gp.PixelRange[YAxis].Min.x + gp.Mx * (x - gp.CurrentPlot->XAxis.Range.Min)),
|
||||
(float)(gp.PixelRange[YAxis].Min.y + gp.My[YAxis] * (y - gp.CurrentPlot->YAxis[YAxis].Range.Min)) );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user