1 /// 2 module plot2d.types; 3 4 import plot2d.util; 5 6 /// 7 struct DimSeg 8 { 9 /// 10 double min = 0, max = 0; 11 12 /// set this.min as min(a,b), this.max as max(a,b) 13 this(double a, double b) 14 { 15 min = .min(a,b); 16 max = .max(a,b); 17 } 18 19 @safe nothrow @nogc: 20 21 /// quantize!round max and min by step and add and sub step 22 void stepExpand(double step) 23 { 24 max = max.quantize!round(step) + step; 25 min = min.quantize!round(step) - step; 26 } 27 28 /// max - min 29 double diff() const @property { return max - min; } 30 } 31 32 /// 33 struct Viewport 34 { 35 /// 36 DimSeg w, h; 37 38 static Viewport initial()(auto ref const Point v) 39 { return Viewport(DimSeg(v.x, v.x), DimSeg(v.y, v.y)); } 40 41 /// 42 void expand()(auto ref const Point p) 43 { 44 set!max(w.max, p.x); 45 set!max(h.max, p.y); 46 set!min(w.min, p.x); 47 set!min(h.min, p.y); 48 } 49 50 /// 51 void expand()(auto ref const Viewport o) 52 { 53 set!max(w.max, o.w.max); 54 set!max(h.max, o.h.max); 55 set!min(w.min, o.w.min); 56 set!min(h.min, o.h.min); 57 } 58 59 /// 60 void expandRel()(auto ref const Point p) 61 { 62 if (p.x > 0) w.max += p.x; 63 else w.min += p.x; // p.x is negative 64 65 if (p.y > 0) h.max += p.y; 66 else h.min += p.y; // p.y is negative 67 } 68 69 /// 70 bool onBinaryRight(string op)(auto ref const Point p) 71 if (op == "in") 72 { 73 return p.x <= w.max && 74 p.x >= w.min && 75 p.y <= h.max && 76 p.y >= h.min; 77 } 78 79 pure @safe nothrow @nogc const @property: 80 81 /// left top 82 Point lt() { return Point(w.min, h.min); } 83 /// left bottom 84 Point lb() { return Point(w.min, h.max); } 85 /// right top 86 Point rt() { return Point(w.max, h.min); } 87 /// right bottom 88 Point rb() { return Point(w.max, h.max); } 89 } 90 91 /// 92 struct Border 93 { 94 /// 95 double left, top, right, bottom; 96 97 /// 98 this(double o) { this(o,o,o,o); } 99 /// 100 this(double x, double y) { this(x,y,x,y); } 101 /// 102 this(double l, double t, double r, double b) 103 { left = l; top = t; right = r; bottom = b; } 104 105 const pure nothrow @safe @property @nogc 106 { 107 /// 108 double sx() { return left + right; } 109 /// 110 double sy() { return top + bottom; } 111 } 112 } 113 114 /// 115 struct Point 116 { 117 /// 118 double x, y; 119 120 const pure nothrow 121 { 122 /// 123 Point opBinary(string op)(auto ref const Point b) 124 { mixin(q{return Point(x %1$s b.x, y %1$s b.y);}.format(op)); } 125 126 /// 127 Point opBinary(string op)(double b) 128 { mixin(q{return Point(x %1$s b, y %1$s b);}.format(op)); } 129 130 /// 131 Point opUnary(string op)() if (op == "-") 132 { return Point(-x, -y); } 133 134 @property 135 { 136 /// 137 double len2() { return x*x + y*y; } 138 /// 139 double len() { return hypot(x, y); } 140 } 141 } 142 } 143 144 /// 145 struct Color 146 { 147 /// 148 double r=0, g=0, b=0, a=1; 149 150 /// 151 auto opBinary(string op)(auto ref const Color c) const pure nothrow 152 { 153 mixin(q{return Color(r %1$s c.r, 154 g %1$s c.g, 155 b %1$s c.b, 156 a %1$s c.a 157 );}.format(op)); 158 } 159 160 /// 161 auto opBinary(string op)(double c) const pure nothrow 162 { 163 mixin(q{return Color(r %1$s c, 164 g %1$s c, 165 b %1$s c, 166 a %1$s c 167 );}.format(op)); 168 } 169 170 static pure nothrow 171 { 172 /// 173 Color red(double v=1, double b=0) { return Color(v, b, b, 1); } 174 /// 175 Color green(double v=1, double b=0) { return Color(b, v, b, 1); } 176 /// 177 Color blue(double v=1, double b=0) { return Color(b, b, v, 1); } 178 /// 179 Color mono(double v=1, double a=1) { return Color(v, v, v, a); } 180 /// 181 Color none() @property { return Color.mono(0, 0); } 182 } 183 }