v01
This commit is contained in:
243
thirdparty/Pangolin/include/pangolin/plot/datalog.h
vendored
Normal file
243
thirdparty/Pangolin/include/pangolin/plot/datalog.h
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
/* This file is part of the Pangolin Project.
|
||||
* http://github.com/stevenlovegrove/Pangolin
|
||||
*
|
||||
* Copyright (c) 2011 Steven Lovegrove
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pangolin/platform.h>
|
||||
|
||||
#include <algorithm> // std::min, std::max
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#if defined(HAVE_EIGEN) && !defined(__CUDACC__) //prevent including Eigen in cuda files
|
||||
#define USE_EIGEN
|
||||
#endif
|
||||
|
||||
#ifdef USE_EIGEN
|
||||
#include <Eigen/Core>
|
||||
#endif
|
||||
|
||||
namespace pangolin
|
||||
{
|
||||
|
||||
/// Simple statistics recorded for a logged input dimension.
|
||||
struct DimensionStats
|
||||
{
|
||||
DimensionStats()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
isMonotonic = true;
|
||||
sum = 0.0f;
|
||||
sum_sq = 0.0f;
|
||||
min = std::numeric_limits<float>::max();
|
||||
max = std::numeric_limits<float>::lowest();
|
||||
}
|
||||
|
||||
void Add(const float v)
|
||||
{
|
||||
isMonotonic = isMonotonic && (v >= max);
|
||||
sum += v;
|
||||
sum_sq += v*v;
|
||||
min = std::min(min, v);
|
||||
max = std::max(max, v);
|
||||
}
|
||||
|
||||
bool isMonotonic;
|
||||
float sum;
|
||||
float sum_sq;
|
||||
float min;
|
||||
float max;
|
||||
};
|
||||
|
||||
class DataLogBlock
|
||||
{
|
||||
public:
|
||||
/// @param dim: dimension of sample
|
||||
/// @param max_samples: maximum number of samples this block can hold
|
||||
/// @param start_id: index of first sample (from entire dataset) in this buffer
|
||||
DataLogBlock(size_t dim, size_t max_samples, size_t start_id)
|
||||
: dim(dim), max_samples(max_samples), samples(0),
|
||||
start_id(start_id)
|
||||
{
|
||||
sample_buffer = std::unique_ptr<float[]>(new float[dim*max_samples]);
|
||||
// stats = std::unique_ptr<DimensionStats[]>(new DimensionStats[dim]);
|
||||
}
|
||||
|
||||
~DataLogBlock()
|
||||
{
|
||||
}
|
||||
|
||||
size_t Samples() const
|
||||
{
|
||||
return samples;
|
||||
}
|
||||
|
||||
size_t MaxSamples() const
|
||||
{
|
||||
return max_samples;
|
||||
}
|
||||
|
||||
/// Return how many more samples can fit in this block
|
||||
size_t SampleSpaceLeft() const
|
||||
{
|
||||
return MaxSamples()- Samples();
|
||||
}
|
||||
|
||||
bool IsFull() const
|
||||
{
|
||||
return Samples() >= MaxSamples();
|
||||
}
|
||||
|
||||
/// Add data to block
|
||||
void AddSamples(size_t num_samples, size_t dimensions, const float* data_dim_major );
|
||||
|
||||
/// Delete all samples
|
||||
void ClearLinked()
|
||||
{
|
||||
samples = 0;
|
||||
nextBlock.reset();
|
||||
}
|
||||
|
||||
DataLogBlock* NextBlock() const
|
||||
{
|
||||
return nextBlock.get();
|
||||
}
|
||||
|
||||
size_t StartId() const
|
||||
{
|
||||
return start_id;
|
||||
}
|
||||
|
||||
float* DimData(size_t d) const
|
||||
{
|
||||
return sample_buffer.get() + d;
|
||||
}
|
||||
|
||||
size_t Dimensions() const
|
||||
{
|
||||
return dim;
|
||||
}
|
||||
|
||||
const float* Sample(size_t n) const
|
||||
{
|
||||
const int id = (int)n - (int)start_id;
|
||||
|
||||
if( 0 <= id && id < (int)samples ) {
|
||||
return sample_buffer.get() + dim*id;
|
||||
}else{
|
||||
if(nextBlock) {
|
||||
return nextBlock->Sample(n);
|
||||
}else{
|
||||
throw std::out_of_range("Index out of range.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
size_t dim;
|
||||
size_t max_samples;
|
||||
size_t samples;
|
||||
size_t start_id;
|
||||
std::unique_ptr<float[]> sample_buffer;
|
||||
// std::unique_ptr<DimensionStats[]> stats;
|
||||
std::unique_ptr<DataLogBlock> nextBlock;
|
||||
};
|
||||
|
||||
/// A DataLog can efficiently record floating point sample data of any size.
|
||||
/// Memory is allocated in blocks is transparent to the user.
|
||||
class PANGOLIN_EXPORT DataLog
|
||||
{
|
||||
public:
|
||||
/// @param block_samples_alloc number of samples each memory block can hold.
|
||||
DataLog(unsigned int block_samples_alloc = 10000 );
|
||||
|
||||
~DataLog();
|
||||
|
||||
/// Provide textual labels corresponding to each dimension logged.
|
||||
/// This information may be used by graphical interfaces to DataLog.
|
||||
void SetLabels(const std::vector<std::string> & labels);
|
||||
const std::vector<std::string>& Labels() const;
|
||||
|
||||
void Log(size_t dimension, const float * vals, unsigned int samples = 1);
|
||||
void Log(float v);
|
||||
void Log(float v1, float v2);
|
||||
void Log(float v1, float v2, float v3);
|
||||
void Log(float v1, float v2, float v3, float v4);
|
||||
void Log(float v1, float v2, float v3, float v4, float v5);
|
||||
void Log(float v1, float v2, float v3, float v4, float v5, float v6);
|
||||
void Log(float v1, float v2, float v3, float v4, float v5, float v6, float v7);
|
||||
void Log(float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8);
|
||||
void Log(float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8, float v9);
|
||||
void Log(float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8, float v9, float v10);
|
||||
void Log(const std::vector<float> & vals);
|
||||
|
||||
#ifdef USE_EIGEN
|
||||
template<typename Derived>
|
||||
void Log(const Eigen::MatrixBase<Derived>& M)
|
||||
{
|
||||
Log( M.rows() * M.cols(), M.template cast<float>().eval().data() );
|
||||
}
|
||||
#endif
|
||||
|
||||
void Clear();
|
||||
void Save(std::string filename);
|
||||
|
||||
// Return first block of stored data
|
||||
const DataLogBlock* FirstBlock() const;
|
||||
|
||||
// Return last block of stored data
|
||||
const DataLogBlock* LastBlock() const;
|
||||
|
||||
// Return number of samples stored in this DataLog
|
||||
size_t Samples() const;
|
||||
|
||||
// Return pointer to stored sample n
|
||||
const float* Sample(int n) const;
|
||||
|
||||
// Return stats computed for each dimension if enabled.
|
||||
const DimensionStats& Stats(size_t dim) const;
|
||||
|
||||
std::mutex access_mutex;
|
||||
|
||||
protected:
|
||||
unsigned int block_samples_alloc;
|
||||
std::vector<std::string> labels;
|
||||
std::unique_ptr<DataLogBlock> block0;
|
||||
DataLogBlock* blockn;
|
||||
std::vector<DimensionStats> stats;
|
||||
bool record_stats;
|
||||
};
|
||||
|
||||
}
|
||||
282
thirdparty/Pangolin/include/pangolin/plot/plotter.h
vendored
Normal file
282
thirdparty/Pangolin/include/pangolin/plot/plotter.h
vendored
Normal file
@@ -0,0 +1,282 @@
|
||||
/* This file is part of the Pangolin Project.
|
||||
* http://github.com/stevenlovegrove/Pangolin
|
||||
*
|
||||
* Copyright (c) 2014 Steven Lovegrove
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PLOTTER_H
|
||||
#define PLOTTER_H
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include <pangolin/display/view.h>
|
||||
#include <pangolin/gl/colour.h>
|
||||
#include <pangolin/gl/gl.h>
|
||||
#include <pangolin/gl/glfont.h>
|
||||
#include <pangolin/gl/glsl.h>
|
||||
#include <pangolin/handler/handler.h>
|
||||
#include <pangolin/plot/datalog.h>
|
||||
#include <pangolin/plot/range.h>
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace pangolin
|
||||
{
|
||||
|
||||
enum DrawingMode
|
||||
{
|
||||
DrawingModePoints = GL_POINTS,
|
||||
DrawingModeDashed = GL_LINES,
|
||||
DrawingModeLine = GL_LINE_STRIP,
|
||||
DrawingModeNone,
|
||||
};
|
||||
|
||||
struct Marker
|
||||
{
|
||||
enum Direction
|
||||
{
|
||||
Horizontal,
|
||||
Vertical
|
||||
};
|
||||
|
||||
enum Equality
|
||||
{
|
||||
LessThan = -1,
|
||||
Equal = 0,
|
||||
GreaterThan = 1
|
||||
};
|
||||
|
||||
Marker(Direction d, float value, Equality leg = Equal, Colour c = Colour() )
|
||||
: colour(c)
|
||||
{
|
||||
if(d == Horizontal) {
|
||||
range.x = Rangef::Open();
|
||||
range.y = Rangef::Containing(value);
|
||||
if(leg == LessThan) {
|
||||
range.y.Insert(std::numeric_limits<float>::lowest() );
|
||||
}else if(leg == GreaterThan) {
|
||||
range.y.Insert(std::numeric_limits<float>::max() );
|
||||
}
|
||||
}else if(d == Vertical) {
|
||||
range.x = Rangef::Containing(value);
|
||||
range.y = Rangef::Open();
|
||||
if(leg == LessThan) {
|
||||
range.x.Insert(std::numeric_limits<float>::lowest() );
|
||||
}else if(leg == GreaterThan) {
|
||||
range.x.Insert(std::numeric_limits<float>::max() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Marker(const XYRangef& range, const Colour& c = Colour() )
|
||||
: range(range), colour(c)
|
||||
{
|
||||
}
|
||||
|
||||
XYRangef range;
|
||||
Colour colour;
|
||||
};
|
||||
|
||||
class PANGOLIN_EXPORT Plotter : public View, Handler
|
||||
{
|
||||
public:
|
||||
Plotter(
|
||||
DataLog* default_log,
|
||||
float left=0, float right=600, float bottom=-1, float top=1,
|
||||
float tickx=30, float ticky=0.5,
|
||||
Plotter* linked_plotter_x = 0,
|
||||
Plotter* linked_plotter_y = 0
|
||||
);
|
||||
|
||||
virtual ~Plotter();
|
||||
|
||||
void Render();
|
||||
|
||||
XYRangef& GetSelection();
|
||||
|
||||
XYRangef& GetDefaultView();
|
||||
void SetDefaultView(const XYRangef& range);
|
||||
|
||||
XYRangef& GetView();
|
||||
void SetView(const XYRangef& range);
|
||||
void SetViewSmooth(const XYRangef& range);
|
||||
|
||||
void ScrollView(float x, float y);
|
||||
void ScrollViewSmooth(float x, float y);
|
||||
|
||||
void ScaleView(float x, float y, float cx, float cy);
|
||||
void ScaleViewSmooth(float x, float y, float cx, float cy);
|
||||
|
||||
void ResetView();
|
||||
|
||||
void SetTicks(float tickx, float ticky);
|
||||
|
||||
void Track(const std::string& x="$i", const std::string& y = "");
|
||||
void ToggleTracking();
|
||||
|
||||
void Trigger(const std::string& x="$0", int edge = -1, float value = 0.0f);
|
||||
void ToggleTrigger();
|
||||
|
||||
void SetBackgroundColour(const Colour& col);
|
||||
void SetAxisColour(const Colour& col);
|
||||
void SetTickColour(const Colour& col);
|
||||
|
||||
void ScreenToPlot(int xpix, int ypix, float &xplot, float &yplot);
|
||||
void Keyboard(View&, unsigned char key, int x, int y, bool pressed);
|
||||
void Mouse(View&, MouseButton button, int x, int y, bool pressed, int mouse_state);
|
||||
void MouseMotion(View&, int x, int y, int mouse_state);
|
||||
void PassiveMouseMotion(View&, int x, int y, int button_state);
|
||||
void Special(View&, InputSpecial inType, float x, float y, float p1, float p2, float p3, float p4, int button_state);
|
||||
|
||||
/// Remove all current series plots
|
||||
void ClearSeries();
|
||||
|
||||
/// Add series X,Y plot from glsl compatible expressions x_expr, y_expr
|
||||
/// $i refers to integral index of datum in log.
|
||||
/// $0, $1, $2, ... refers to nth series in log.
|
||||
/// e.g. x_expr = "$i", y_expr = "$0" // index - data[0] plot
|
||||
/// e.g. x_expr = "$0", y_expr = "$1" // data[0], data[1] X-Y plot
|
||||
/// e.g. x_exptr ="$i", y_expr = "sqrt($1)} // index - sqrt(data[0]) plot
|
||||
void AddSeries(const std::string& x_expr, const std::string& y_expr,
|
||||
DrawingMode drawing_mode = DrawingModeLine, Colour colour = Colour::Unspecified(),
|
||||
const std::string &title = "$y", DataLog* log = nullptr
|
||||
);
|
||||
|
||||
std::string PlotTitleFromExpr(const std::string& expr) const;
|
||||
|
||||
/// Remove all current markers
|
||||
void ClearMarkers();
|
||||
|
||||
/// Add horizontal or vertical inequality marker; equal-to, less-than, or greater than.
|
||||
/// This is useful for annotating a critical point or valid region.
|
||||
Marker& AddMarker(
|
||||
Marker::Direction d, float value,
|
||||
Marker::Equality leg = Marker::Equal, Colour c = Colour()
|
||||
);
|
||||
|
||||
Marker& AddMarker( const Marker& marker );
|
||||
|
||||
void ClearImplicitPlots();
|
||||
void AddImplicitPlot();
|
||||
|
||||
/// Reset colour wheel to initial state. May be useful together with ClearSeries() / ClearMarkers()
|
||||
void ResetColourWheel();
|
||||
|
||||
protected:
|
||||
struct PANGOLIN_EXPORT Tick
|
||||
{
|
||||
float val;
|
||||
float factor;
|
||||
std::string symbol;
|
||||
};
|
||||
|
||||
struct PANGOLIN_EXPORT PlotAttrib
|
||||
{
|
||||
PlotAttrib(std::string name, int plot_id, int location = -1)
|
||||
: name(name), plot_id(plot_id), location(location) { }
|
||||
|
||||
std::string name;
|
||||
int plot_id;
|
||||
int location;
|
||||
};
|
||||
|
||||
struct PANGOLIN_EXPORT PlotSeries
|
||||
{
|
||||
PlotSeries();
|
||||
void CreatePlot(const std::string& x, const std::string& y, Colour c, std::string title);
|
||||
|
||||
GlSlProgram prog;
|
||||
GlText title;
|
||||
bool contains_id;
|
||||
std::vector<PlotAttrib> attribs;
|
||||
DataLog* log;
|
||||
GLenum drawing_mode;
|
||||
Colour colour;
|
||||
bool used;
|
||||
};
|
||||
|
||||
struct PANGOLIN_EXPORT PlotImplicit
|
||||
{
|
||||
// Assign to gl_FragColor
|
||||
void CreatePlot(const std::string& code);
|
||||
|
||||
// Expression uses x,y and assignes colours [0,1] to r,g,b,a
|
||||
void CreateColouredPlot(const std::string& code);
|
||||
|
||||
// Expression uses x,y and evaluates to true/false;
|
||||
void CreateInequality(const std::string& ie, Colour c);
|
||||
|
||||
// Expression uses x,y and evaluates to a number
|
||||
void CreateDistancePlot(const std::string& dist);
|
||||
|
||||
GlSlProgram prog;
|
||||
};
|
||||
|
||||
void FixSelection();
|
||||
void UpdateView();
|
||||
Tick FindTickFactor(float tick);
|
||||
|
||||
DataLog* default_log;
|
||||
|
||||
ColourWheel colour_wheel;
|
||||
Colour colour_bg;
|
||||
Colour colour_tk;
|
||||
Colour colour_ax;
|
||||
|
||||
GlSlProgram prog_lines;
|
||||
GlSlProgram prog_text;
|
||||
|
||||
std::vector<PlotSeries> plotseries;
|
||||
std::vector<Marker> plotmarkers;
|
||||
std::vector<PlotImplicit> plotimplicits;
|
||||
|
||||
Tick tick[2];
|
||||
XYRangef rview_default;
|
||||
XYRangef rview;
|
||||
XYRangef target;
|
||||
XYRangef selection;
|
||||
|
||||
void ComputeTrackValue( float track_val[2] );
|
||||
XYRangef ComputeAutoSelection();
|
||||
|
||||
bool track;
|
||||
std::string track_x;
|
||||
std::string track_y;
|
||||
float last_track_val[2];
|
||||
|
||||
// -1: falling, -0:disable, 1: rising
|
||||
int trigger_edge;
|
||||
float trigger_value;
|
||||
std::string trigger;
|
||||
|
||||
float hover[2];
|
||||
int last_mouse_pos[2];
|
||||
|
||||
Plotter* linked_plotter_x;
|
||||
Plotter* linked_plotter_y;
|
||||
};
|
||||
|
||||
} // namespace pangolin
|
||||
|
||||
#endif // PLOTTER_H
|
||||
372
thirdparty/Pangolin/include/pangolin/plot/range.h
vendored
Normal file
372
thirdparty/Pangolin/include/pangolin/plot/range.h
vendored
Normal file
@@ -0,0 +1,372 @@
|
||||
/* This file is part of the Pangolin Project.
|
||||
* http://github.com/stevenlovegrove/Pangolin
|
||||
*
|
||||
* Copyright (c) 2014 Steven Lovegrove
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pangolin/platform.h>
|
||||
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
//prevent including Eigen in cuda files
|
||||
#if defined(HAVE_EIGEN) && !defined(__CUDACC__)
|
||||
# define USE_EIGEN
|
||||
#endif
|
||||
|
||||
#ifdef USE_EIGEN
|
||||
# include <Eigen/Core>
|
||||
# include <Eigen/src/Geometry/AlignedBox.h>
|
||||
#endif // USE_EIGEN
|
||||
|
||||
namespace pangolin
|
||||
{
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct Range
|
||||
{
|
||||
static Range<T> Open()
|
||||
{
|
||||
return Range<T>(std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());
|
||||
}
|
||||
|
||||
static Range<T> Empty()
|
||||
{
|
||||
return Range<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::lowest());
|
||||
}
|
||||
|
||||
static Range<T> Containing(T val)
|
||||
{
|
||||
return Range<T>(val, val);
|
||||
}
|
||||
|
||||
Range()
|
||||
: min(+std::numeric_limits<T>::max()),
|
||||
max(-std::numeric_limits<T>::max())
|
||||
{
|
||||
}
|
||||
|
||||
Range(T rmin, T rmax)
|
||||
: min(rmin), max(rmax)
|
||||
{
|
||||
}
|
||||
|
||||
Range operator+(T v)
|
||||
{
|
||||
return Range(min+v, max+v);
|
||||
}
|
||||
|
||||
Range operator-(T v)
|
||||
{
|
||||
return Range(min-v, max-v);
|
||||
}
|
||||
|
||||
Range& operator+=(T v)
|
||||
{
|
||||
min += v;
|
||||
max += v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Range& operator-=(T v)
|
||||
{
|
||||
min -= v;
|
||||
max -= v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Range& operator*=(T v)
|
||||
{
|
||||
min *= v;
|
||||
max *= v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Range& operator/=(T v)
|
||||
{
|
||||
min /= v;
|
||||
max /= v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Range& operator+=(const Range& o)
|
||||
{
|
||||
min += o.min;
|
||||
max += o.max;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Range& operator-=(const Range& o)
|
||||
{
|
||||
min -= o.min;
|
||||
max -= o.max;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Range operator+(const Range& o) const
|
||||
{
|
||||
return Range(min + o.min, max + o.max);
|
||||
}
|
||||
|
||||
Range operator-(const Range& o) const
|
||||
{
|
||||
return Range(min - o.min, max - o.max);
|
||||
}
|
||||
|
||||
Range operator*(float s) const
|
||||
{
|
||||
return Range(T(s*min), T(s*max));
|
||||
}
|
||||
|
||||
T Size() const
|
||||
{
|
||||
return max - min;
|
||||
}
|
||||
|
||||
T AbsSize() const
|
||||
{
|
||||
return std::abs(Size());
|
||||
}
|
||||
|
||||
T Mid() const
|
||||
{
|
||||
return (min + max) / (T)2.0f;
|
||||
}
|
||||
|
||||
void Scale(float s, float center = 0.0f)
|
||||
{
|
||||
min = T(s*(min-center) + center);
|
||||
max = T(s*(max-center) + center);
|
||||
}
|
||||
|
||||
void Insert(T v)
|
||||
{
|
||||
min = std::min(min,v);
|
||||
max = std::max(max,v);
|
||||
}
|
||||
|
||||
void Insert(const Range<T>& r)
|
||||
{
|
||||
Insert(r.min);
|
||||
Insert(r.max);
|
||||
}
|
||||
|
||||
void Clamp(T vmin, T vmax)
|
||||
{
|
||||
min = std::min(std::max(vmin, min), vmax);
|
||||
max = std::min(std::max(vmin, max), vmax);
|
||||
}
|
||||
|
||||
void Clamp(const Range& o)
|
||||
{
|
||||
Clamp(o.min, o.max);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
min = std::numeric_limits<T>::max();
|
||||
max = std::numeric_limits<T>::lowest();
|
||||
}
|
||||
|
||||
bool Contains(T v) const
|
||||
{
|
||||
return min <= v && v <= max;
|
||||
}
|
||||
|
||||
bool ContainsWeak(T v) const
|
||||
{
|
||||
return (min <= v && v <= max)
|
||||
|| (max <= v && v <= min);
|
||||
}
|
||||
|
||||
template<typename To>
|
||||
Range<To> Cast() const
|
||||
{
|
||||
return Range<To>(To(min), To(max));
|
||||
}
|
||||
|
||||
T min;
|
||||
T max;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct XYRange
|
||||
{
|
||||
static XYRange<T> Open()
|
||||
{
|
||||
return XYRange<T>(
|
||||
Range<T>(std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max()),
|
||||
Range<T>(std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max())
|
||||
);
|
||||
}
|
||||
|
||||
static XYRange<T> Empty()
|
||||
{
|
||||
return XYRange<T>(
|
||||
Range<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::lowest()),
|
||||
Range<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::lowest())
|
||||
);
|
||||
}
|
||||
|
||||
static XYRange<T> Containing(T x, T y)
|
||||
{
|
||||
return XYRange<T>(
|
||||
Range<T>(x, x),
|
||||
Range<T>(y, y)
|
||||
);
|
||||
}
|
||||
|
||||
XYRange()
|
||||
{
|
||||
}
|
||||
|
||||
XYRange(const Range<T>& xrange, const Range<T>& yrange)
|
||||
: x(xrange), y(yrange)
|
||||
{
|
||||
}
|
||||
|
||||
XYRange(T xmin, T xmax, T ymin, T ymax)
|
||||
: x(xmin,xmax), y(ymin,ymax)
|
||||
{
|
||||
}
|
||||
|
||||
XYRange operator-(const XYRange& o) const
|
||||
{
|
||||
return XYRange(x - o.x, y - o.y);
|
||||
}
|
||||
|
||||
XYRange operator*(float s) const
|
||||
{
|
||||
return XYRange(x*s, y*s);
|
||||
}
|
||||
|
||||
XYRange& operator+=(const XYRange& o)
|
||||
{
|
||||
x += o.x;
|
||||
y += o.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Scale(float sx, float sy, float centerx, float centery)
|
||||
{
|
||||
x.Scale(sx, centerx);
|
||||
y.Scale(sy, centery);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
x.Clear();
|
||||
y.Clear();
|
||||
}
|
||||
|
||||
void Clamp(T xmin, T xmax, T ymin, T ymax)
|
||||
{
|
||||
x.Clamp(xmin,xmax);
|
||||
y.Clamp(ymin,ymax);
|
||||
}
|
||||
|
||||
void Clamp(const XYRange& o)
|
||||
{
|
||||
x.Clamp(o.x);
|
||||
y.Clamp(o.y);
|
||||
}
|
||||
|
||||
void Insert(T xval, T yval)
|
||||
{
|
||||
x.Insert(xval);
|
||||
y.Insert(yval);
|
||||
}
|
||||
|
||||
void Insert(XYRange<T> r)
|
||||
{
|
||||
x.Insert(r.x);
|
||||
y.Insert(r.y);
|
||||
}
|
||||
|
||||
float Area() const
|
||||
{
|
||||
return x.Size() * y.Size();
|
||||
}
|
||||
|
||||
bool Contains(float px, float py) const
|
||||
{
|
||||
return x.Contains(px) && y.Contains(py);
|
||||
}
|
||||
|
||||
bool ContainsWeak(float px, float py) const
|
||||
{
|
||||
return x.ContainsWeak(px) && y.ContainsWeak(py);
|
||||
}
|
||||
|
||||
template<typename To>
|
||||
XYRange<To> Cast() const
|
||||
{
|
||||
return XYRange<To>(
|
||||
x.template Cast<To>(),
|
||||
y.template Cast<To>()
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef USE_EIGEN
|
||||
operator Eigen::AlignedBox<T,2>() const {
|
||||
return Eigen::AlignedBox<T,2>(
|
||||
Eigen::Matrix<T,2,1>(x.min, y.min),
|
||||
Eigen::Matrix<T,2,1>(x.max, y.max)
|
||||
);
|
||||
}
|
||||
|
||||
Eigen::Matrix<T,2,1> Center() const {
|
||||
return Eigen::Matrix<T,2,1>(x.Mid(), y.Mid());
|
||||
}
|
||||
#endif
|
||||
|
||||
Range<T> x;
|
||||
Range<T> y;
|
||||
};
|
||||
|
||||
typedef Range<int> Rangei;
|
||||
typedef Range<float> Rangef;
|
||||
typedef Range<double> Ranged;
|
||||
|
||||
typedef XYRange<int> XYRangei;
|
||||
typedef XYRange<float> XYRangef;
|
||||
typedef XYRange<double> XYRanged;
|
||||
|
||||
template<typename T> inline
|
||||
Rangei Round(const Range<T>& r)
|
||||
{
|
||||
return Rangei( int(r.min+0.5), int(r.max+0.5) );
|
||||
}
|
||||
|
||||
template<typename T> inline
|
||||
XYRangei Round(const XYRange<T>& r)
|
||||
{
|
||||
return XYRangei( Round(r.x), Round(r.y) );
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user