void draw_plot(RendererViewport r, Plot plot) { switch (plot.get_dimensions()) { case 1: { set_2d_plot_window(r, plot); draw_axes_2d(r, plot.get_axes()); // plot title Vector2Pair _window2d = r.get_window2d(); Vector2Pair _window2d_fit = r.get_window2d_fit(); r.draw_text( new Vector2((_window2d.v0.x() + _window2d.v1.x()) / 2.0, (_window2d_fit.v1.y() + _window2d.v1.y()) / 2.0), Vector2.vector2_10, plot.get_title(), (int)Renderer.TextAlignMask.TextAlignCenter | (int)Renderer.TextAlignMask.TextAlignMiddle, 18, r.get_style_color(Renderer.Style.StyleForeground)); // plot data for (int i = 0; i < plot.get_plot_count(); i++) { PlotData d = plot.get_plot_data(i); draw_plot_data_2d(r, (Set1d)d.get_set(), d); } break; } default: throw new InvalidOperationException("Unsupported dimensions " + plot.get_dimensions()); } }
void set_margin_output(double left, double bottom, double right, double top) { _margin_type = margin_type_e.MarginOutput; _margin = new Vector2Pair(new Vector2(left, bottom), new Vector2(right, top)); set_window(_window2d_fit, false); }
public virtual void draw_box(Vector2Pair c, Rgb rgb) { draw_segment(new Vector2(c.v0.x(), c.v0.y()), new Vector2(c.v1.x(), c.v0.y()), rgb); draw_segment(new Vector2(c.v1.x(), c.v1.y()), new Vector2(c.v1.x(), c.v0.y()), rgb); draw_segment(new Vector2(c.v1.x(), c.v1.y()), new Vector2(c.v0.x(), c.v1.y()), rgb); draw_segment(new Vector2(c.v0.x(), c.v0.y()), new Vector2(c.v0.x(), c.v1.y()), rgb); }
public void set_window(Vector2 center, Vector2 size, bool keep_aspect) { Vector2 s = size; if (keep_aspect) { double out_ratio = (_2d_output_res.x() / _cols) / (_2d_output_res.y() / _rows); if (Math.Abs(s.x() / s.y()) < out_ratio) { //s.x () = s.y () * out_ratio; s = new Vector2(s.y() * out_ratio, s.y()); } else { //s.y () = s.x () / out_ratio; s = new Vector2(s.x(), s.x() / out_ratio); } } Vector2 sby2 = s.divide(2.0); // (center - s / 2., center + s / 2.) _window2d_fit = new Vector2Pair(center.minus(sby2), center.plus(sby2)); Vector2 ms0 = sby2; Vector2 ms1 = sby2; switch (_margin_type) { case margin_type_e.MarginLocal: // ms[0] = ms[0] + _margin[0]; // ms[1] = ms[1] + _margin[1]; ms0 = ms0.plus(_margin.v0); ms1 = ms1.plus(_margin.v1); break; case margin_type_e.MarginRatio: // ms[0] = ms[0] + s.mul (_margin[0]); // ms[1] = ms[1] + s.mul (_margin[1]); ms0 = ms0.plus(s.ebeTimes(_margin.v0)); ms1 = ms1.plus(s.ebeTimes(_margin.v1)); break; case margin_type_e.MarginOutput: // ms[0] = ms[0] / (math::vector2_1 - _margin[0] / _2d_output_res * 2); // ms[1] = ms[1] / (math::vector2_1 - _margin[1] / _2d_output_res * 2); ms0 = ms0.ebeDivide(Vector2.vector2_1.minus(_margin.v0.ebeDivide(_2d_output_res.times(2.0)))); ms1 = ms1.ebeDivide(Vector2.vector2_1.minus(_margin.v1.ebeDivide(_2d_output_res.times(2.0)))); break; } //(center - ms[0], center + ms[1]) _window2d = new Vector2Pair(center.minus(ms0), center.plus(ms1)); update_2d_window(); set_orthographic(); set_page(_pageid); }
public override void draw_segment(Vector2Pair l, Rgb rgb) { Vector2 v2da = trans_pos(l.v0); Vector2 v2db = trans_pos(l.v1); svg_begin_line(v2da.x(), v2da.y(), v2db.x(), v2db.y(), false); svg_add_stroke(rgb); svg_end(); }
void draw_2d_fit(RendererViewport r, OpticalSystem system, bool keep_aspect) { Vector3Pair b = system.get_bounding_box(); r.set_window(Vector2Pair.from(b, 2, 1), keep_aspect); r.set_camera_direction(Vector3.vector3_100); r.set_camera_position(Vector3.vector3_0); r.set_feature_size(b.v1.y() - b.v0.y() / 20.0); }
public void set_window(Vector2Pair window, bool keep_aspect) { //(window[0] + window[1]) / 2 Vector2 center = window.v0.plus(window.v1).divide(2.0); //(window[1].x () - window[0].x (), //window[1].y () - window[0].y ()); Vector2 size = new Vector2(window.v1.x() - window.v0.x(), window.v1.y() - window.v0.y()); set_window(center, size, keep_aspect); }
void draw_frame_2d(RendererViewport r) { Vector2[] fr = new Vector2[4]; Vector2Pair _window2d_fit = r.get_window2d_fit(); fr[0] = _window2d_fit.v0; fr[1] = new Vector2(_window2d_fit.v0.x(), _window2d_fit.v1.y()); fr[2] = _window2d_fit.v1; fr[3] = new Vector2(_window2d_fit.v1.x(), _window2d_fit.v0.y()); r.draw_polygon(fr, r.get_style_color(Renderer.Style.StyleForeground), false, true); }
void draw_axes_tic2(RendererViewport r, PlotAxes a, int i, int pow10, bool oor, double x) { const int N = 2; Vector2 p = new Vector2(a.get_position().x(), a.get_position().y()); PlotAxes.Axis ax = a._axes[i]; Vector2 vtic = null; Vector2Pair _window2d_fit = r.get_window2d_fit(); if (!oor && ax._axis) { vtic = p; vtic = vtic.set(i, x + p.v(i)); r.draw_point(vtic, r.get_style_color(Renderer.Style.StyleForeground), Renderer.PointStyle.PointStyleCross); } if (a._frame) { vtic = _window2d_fit.v1; vtic = vtic.set(i, x + p.v(i)); r.draw_point(vtic, r.get_style_color(Renderer.Style.StyleForeground), Renderer.PointStyle.PointStyleCross); vtic = _window2d_fit.v0; vtic = vtic.set(i, x + p.v(i)); r.draw_point(vtic, r.get_style_color(Renderer.Style.StyleForeground), Renderer.PointStyle.PointStyleCross); } // draw tic value text if (ax._values) { int align0 = (int)Renderer.TextAlignMask.TextAlignCenter | (int)Renderer.TextAlignMask.TextAlignTop; int align1 = (int)Renderer.TextAlignMask.TextAlignRight | (int)Renderer.TextAlignMask.TextAlignMiddle; int align2 = (int)Renderer.TextAlignMask.TextAlignTop | (int)Renderer.TextAlignMask.TextAlignCenter; string s = String.Format("{0:G3}", (x + p.v(i) - a._origin.v(i)) / Math.Pow(10.0, pow10)); switch (N) { case 2: int align = i == 0 ? align0 : (i == 1 ? align1 : align2); r.draw_text(vtic, Vector2.vector2_10, s, align, 12, r.get_style_color(Renderer.Style.StyleForeground)); break; } } }
protected RendererViewport() { _margin_type = margin_type_e.MarginRatio; _margin = new Vector2Pair(new Vector2(0.13, 0.13), new Vector2(0.13, 0.13)); _rows = 1; _cols = 1; _pageid = 0; _fov = 45.0; _page = Vector2Pair.vector2_pair_00; _window2d = Vector2Pair.vector2_pair_00; _window2d_fit = Vector2Pair.vector2_pair_00; _2d_output_res = Vector2.vector2_0; //_precision (3), _format () }
public double ln_intersect_ln_scale(Vector2Pair line) { // based on // http://geometryalgorithms.com/Archive/algorithm_0104/algorithm_0104B.htm Vector2 w = v0.minus(line.v0); double d = v1.x() * line.v1.y() - v1.y() * line.v1.x(); if (Math.Abs(d) < 1e-10) { throw new InvalidOperationException("ln_intersect_ln_scale: lines are parallel"); } double s = (line.v1.x() * w.y() - line.v1.y() * w.x()) / d; return(s); }
public override void set_perspective() { double out_ratio = (_2d_output_res.y() / _rows) / (_2d_output_res.x() / _cols); if (out_ratio < 1.0) { _window2d = new Vector2Pair(new Vector2(-1.0 / out_ratio, -1.0), new Vector2(1.0 / out_ratio, 1.0)); } else { _window2d = new Vector2Pair(new Vector2(-1.0, -out_ratio), new Vector2(1.0, out_ratio)); } _window2d_fit = _window2d; update_2d_window(); set_page(_pageid); _projection_type = ProjectionType.Perspective; _eye_dist = 1.0 / Math.Tan(MathUtils.ToRadians(_fov) / 2.0); }
public void set_page(int page) { if (page >= _cols * _rows) { throw new InvalidOperationException("set_page: no such page number in current layout"); } _pageid = page; int row = page / _cols; int col = page % _cols; Vector2 size = new Vector2(_window2d.v1.x() - _window2d.v0.x(), _window2d.v1.y() - _window2d.v0.y()); Vector2 a = new Vector2(_window2d.v0.x() - size.x() * col, _window2d.v0.y() - size.y() * (_rows - 1 - row)); Vector2 b = new Vector2(a.x() + size.x() * _cols, a.y() + size.y() * _rows); _page = new Vector2Pair(a, b); }
public override Vector3Pair get_bounding_box() { Vector2Pair sb = _shape.get_bounding_box(); // FIXME we assume curve is symmetric here double z = 0; double ms = _curve.sagitta(new Vector2(_shape.max_radius())); if (Double.IsNaN(ms)) { Console.WriteLine("Invalid sagitta at " + _shape.max_radius()); return(null); } if (z > ms) { double temp = z; z = ms; ms = temp; } return(new Vector3Pair(new Vector3(sb.v0.x(), sb.v0.y(), z), new Vector3(sb.v1.x(), sb.v1.y(), ms))); }
public Vector2 ln_intersect_ln(Vector2Pair line) { return(v0.plus(v1.times(ln_intersect_ln_scale(line)))); }
public bool isEquals(Vector2Pair other, double tolerance) { return(v0.isEqual(other.v0, tolerance) && v1.isEqual(other.v1, tolerance)); }
public void draw_axes_2d(RendererViewport renderer, PlotAxes a) { int N = 2; Vector2 p = new Vector2(a.get_position().x(), a.get_position().y()); int pow10; int[] max = new int[N]; int[] min = new int[N]; double[] step = new double[N]; Vector2Pair _window2d = renderer.get_window2d(); Vector2Pair _window2d_fit = renderer.get_window2d_fit(); if (a._frame) { draw_frame_2d(renderer); } for (int i = 0; i < N; i++) { PlotAxes.Axis ax = a._axes[i]; Range r = new Range(_window2d_fit.v0.v(i), _window2d_fit.v1.v(i)); double s = step[i] = Math.Abs(a.get_tics_step(i, r)); min[i] = MathUtils.trunc((r.first - p.v(i)) / s); max[i] = MathUtils.trunc((r.second - p.v(i)) / s); pow10 = ax._pow10_scale ? (int)Math.Floor(Math.Log10(s)) : 0; string si_unit = ""; if (ax._si_prefix) { int u = (24 + pow10 + ax._pow10) / 3; if (u >= 0 && u < 17) { si_unit = sc[u] + ax._unit; pow10 = (u - 8) * 3 - ax._pow10; } } Vector2 lp = null; Vector2 ld = null; switch (i) { case 0: lp = new Vector2( (_window2d.v0.x() + _window2d.v1.x()) / 2.0, (_window2d_fit.v0.y() * .50 + _window2d.v0.y() * 1.50) / 2.0); ld = Vector2.vector2_10; break; case 1: lp = new Vector2( (_window2d_fit.v0.x() * .50 + _window2d.v0.x() * 1.50) / 2.0, (_window2d.v0.y() + _window2d.v1.y()) / 2.0); ld = Vector2.vector2_01; break; default: throw new InvalidOperationException("Invalid axis " + i); } // axis label { string lx = ax._label; bool useunit = ax._unit.Length > 0; bool usep10 = pow10 != 0; if (si_unit.Length > 0) { lx += " (" + si_unit + ")"; } else if (useunit || usep10) { lx += " ("; if (usep10) { //lx += string.format("x10^%i", pow10); lx += string.Format("x10^{0:D}", pow10); } if (useunit && usep10) { lx += " "; } if (useunit) { lx += ax._unit; } lx += ")"; } renderer.draw_text(lp, ld, lx, (int)Renderer.TextAlignMask.TextAlignCenter | (int)Renderer.TextAlignMask.TextAlignMiddle, 12, renderer.get_style_color(Renderer.Style.StyleForeground)); } // skip out of range axis bool oor = false; for (int j = 0; j < N; j++) { oor |= (j != i && ((p.v(j) <= Math.Min(_window2d_fit.v0.v(j), _window2d_fit.v1.v(j))) || (p.v(j) >= Math.Max(_window2d_fit.v0.v(j), _window2d_fit.v1.v(j))))); } // draw axis if (!oor && ax._axis) { Vector2Pair seg = new Vector2Pair(p.set(i, r.first), p.set(i, r.second)); renderer.draw_segment(seg, renderer.get_style_color(Renderer.Style.StyleForeground)); } // draw tics on axis if (ax._tics && (ax._axis || a._frame)) { for (int j = min[i]; j <= max[i]; j++) { draw_axes_tic2(renderer, a, i, pow10, oor, j * s); } } } if (a._grid) { // draw grid for (int x = min[0]; x <= max[0]; x++) { for (int y = min[1]; y <= max[1]; y++) { switch (N) { // case 3: // for (int z = min[2]; z <= max[2]; z++) // renderer.draw_point (new Vector3 (p[0] + x * step[0], // p[1] + y * step[1], // p[2] + z * step[2]), // renderer.get_style_color (StyleForeground)); // break; case 2: renderer.draw_point( new Vector2(p.v(0) + x * step[0], p.v(1) + y * step[1]), renderer.get_style_color(Renderer.Style.StyleForeground), Renderer.PointStyle.PointStyleDot); break; } } } } }
/** Draw a line segment in 2d */ public virtual void draw_segment(Vector2Pair s) { draw_segment(s, Rgb.rgb_gray); }
public abstract void draw_segment(Vector2Pair s, Rgb rgb);
static void draw_ray_line(Renderer r, Vector2Pair l, TracedRay ray) { r.draw_segment(l, ray_to_rgb(ray)); }
void draw_plot_data_2d(RendererViewport r, Set1d data, PlotData style) { // spline interpolated curve between points Vector2Pair _window2d_fit = r.get_window2d_fit(); Vector2Pair _window2d = r.get_window2d(); Vector2 _2d_output_res = r.get_2d_output_res(); if ((style.get_style() & (int)PlotStyleMask.InterpolatePlot) != 0) { double x_step = (_window2d.v1.x() - _window2d.v0.x()) / _2d_output_res.x(); Range xr = data.get_x_range(0); double x_low = Math.Max(_window2d_fit.v0.x(), xr.first); double x_high = Math.Min(_window2d_fit.v1.x(), xr.second); double y1 = data.interpolate(x_low); for (double x = x_low + x_step; x < x_high + x_step / 2; x += x_step) { double y2 = data.interpolate(x); r.draw_segment(new Vector3Pair(new Vector3(x - x_step, y1, 0), new Vector3(x, y2, 0)), style.get_color()); y1 = y2; } } // line plot if ((style.get_style() & (int)PlotStyleMask.LinePlot) != 0) { Range p1 = new Range(data.get_x_value(0), data.get_y_value(0)); for (int j = 1; j < data.get_count(); j++) { Range p2 = new Range(data.get_x_value(j), data.get_y_value(j)); r.draw_segment( new Vector3Pair(new Vector3(p1.first, p1.second, 0), new Vector3(p2.first, p2.second, 0)), style.get_color()); p1 = p2; } } // draw cross tic for each point if ((style.get_style() & (int)PlotStyleMask.PointPlot) != 0) { for (int j = 0; j < data.get_count(); j++) { Vector2 p = new Vector2(data.get_x_value(j), data.get_y_value(j)); r.draw_point(p, style.get_color(), Renderer.PointStyle.PointStyleCross); } } // print value for each point if ((style.get_style() & (int)PlotStyleMask.ValuePlot) != 0) { for (int j = 0; j < data.get_count(); j++) { int a; // FIXME remove use of data pair Range p = new Range(data.get_x_value(j), data.get_y_value(j)); double prev = j > 0 ? data.get_y_value(j - 1) : p.second; double next = j + 1 < data.get_count() ? data.get_y_value(j + 1) : p.second; if (p.second > prev) // FIXME use derivative to find best text position { if (p.second > next) { a = (int)Renderer.TextAlignMask.TextAlignBottom | (int)Renderer.TextAlignMask.TextAlignCenter; } else { a = (int)Renderer.TextAlignMask.TextAlignBottom | (int)Renderer.TextAlignMask.TextAlignRight; } } else { if (p.second > next) { a = (int)Renderer.TextAlignMask.TextAlignTop | (int)Renderer.TextAlignMask.TextAlignRight; } else { a = (int)Renderer.TextAlignMask.TextAlignBottom | (int)Renderer.TextAlignMask.TextAlignLeft; } } string s = string.Format("{0:F2}", p.second); r.draw_text(new Vector2(p.first, p.second), Vector2.vector2_10, s, a, 12, style.get_color()); } } }