public override void get_contour(int contour, PatternConsumer f, double resolution) { const double epsilon = 1e-8; Vector2 step = get_step(resolution); double x, y; for (x = -_halfsize.x(); x < _halfsize.x() - epsilon; x += step.x()) { f(new Vector2(x, -_halfsize.y())); } for (y = -_halfsize.y(); y < _halfsize.y() - epsilon; y += step.y()) { f(new Vector2(_halfsize.x(), y)); } for (x = _halfsize.x(); x > -_halfsize.x() + epsilon; x -= step.x()) { f(new Vector2(x, _halfsize.y())); } for (y = _halfsize.y(); y > -_halfsize.y() + epsilon; y -= step.y()) { f(new Vector2(-_halfsize.x(), y)); } }
private void add_pattern_point(Vector2 v, bool unobstructed, Shape shape, PatternConsumer f) { if (unobstructed || shape.inside(v)) { f(v); } }
public void get_pattern(ConsumerVector3 f, Distribution d, bool unobstructed) { PatternConsumer de = (v2d) => { f(new Vector3(v2d.x(), v2d.y(), _curve.sagitta(v2d))); }; // get distribution from shape _shape.get_pattern(de, d, unobstructed); }
public void testShapes() { for (int i = 0; i < st.Length; i++) { shape_test_s s = st[i]; string fname = String.Format("test_shape_{0}.svg", s.name); RendererSvg rsvg = new RendererSvg(800, 600, Rgb.rgb_black); RendererViewport r = rsvg; r.set_window(Vector2.vector2_0, 70.0, true); { ConsumerTriangle2 d = (Triangle2 t) => { r.draw_triangle(t, true, new Rgb(.2, .2, .2, 1.0)); r.draw_triangle(t, false, Rgb.rgb_gray); }; s.s.get_triangles(d, 10.0); } for (int c = 0; c < s.s.get_contour_count(); c++) { List <Vector2> poly = new (); PatternConsumer d = (Vector2 v) => { poly.Add(v); }; s.s.get_contour(c, d, 10.0); r.draw_polygon(poly.ToArray(), Rgb.rgb_yellow, false, true); } for (double a = 0; a < 2.0 * Math.PI - 1e-8; a += 2.0 * Math.PI / 50.0) { Vector2 d = new Vector2(Math.Cos(a), Math.Sin(a)); double ro = s.s.get_outter_radius(d); r.draw_point(d.times(ro), Rgb.rgb_magenta, Renderer.PointStyle.PointStyleCross); double rh = s.s.get_hole_radius(d); r.draw_point(d.times(rh), Rgb.rgb_cyan, Renderer.PointStyle.PointStyleCross); } r.draw_circle(Vector2.vector2_0, s.s.max_radius(), Rgb.rgb_red, false); r.draw_circle(Vector2.vector2_0, s.s.min_radius(), Rgb.rgb_blue, false); r.draw_box(s.s.get_bounding_box(), Rgb.rgb_cyan); { PatternConsumer d = (Vector2 v) => { r.draw_point(v, Rgb.rgb_green, Renderer.PointStyle.PointStyleDot); }; Distribution dist = new Distribution(); ((ShapeBase)s.s).get_base_pattern(d, dist, false); } Console.WriteLine(rsvg.write(new StringBuilder()).ToString()); } }
public override void get_contour(int contour, PatternConsumer f, double resolution) { const double epsilon = 1e-8; double xyr = 1.0 / get_xy_ratio(); double r; if (hole && contour == 1) { r = get_internal_xradius(); } else { r = get_external_xradius(); } double astep1 = (Math.PI / 3.0) / Math.Round(r / get_radial_step(resolution)); for (double a1 = 0; a1 < 2 * Math.PI - epsilon; a1 += astep1) { f(new Vector2(Math.Cos(a1) * r, Math.Sin(a1) * r * xyr)); } }
public override void get_pattern(PatternConsumer f, Distribution d, bool unobstructed) { const double epsilon = 1e-8; Vector2 hs = _halfsize.times(d.get_scaling()); Vector2 step = hs.divide((double)(d.get_radial_density() / 2.0)); switch (d.get_pattern()) { case Pattern.MeridionalDist: { f(Vector2.vector2_0); for (double y = step.y(); y < hs.y() + epsilon; y += step.y()) { f(new Vector2(0, y)); f(new Vector2(0, -y)); } break; } case Pattern.SagittalDist: { f(Vector2.vector2_0); for (double x = step.x(); x < hs.x() + epsilon; x += step.x()) { f(new Vector2(x, 0)); f(new Vector2(-x, 0)); } break; } case Pattern.CrossDist: { f(Vector2.vector2_0); for (double x = step.x(); x < hs.x() + epsilon; x += step.x()) { f(new Vector2(x, 0)); f(new Vector2(-x, 0)); } for (double y = step.y(); y < hs.y() + epsilon; y += step.y()) { f(new Vector2(0, y)); f(new Vector2(0, -y)); } break; } case Pattern.DefaultDist: case Pattern.SquareDist: { double x, y; f(Vector2.vector2_0); for (x = step.x(); x < hs.x() + epsilon; x += step.x()) { for (y = step.y(); y < hs.y() + epsilon; y += step.y()) { f(new Vector2(x, y)); f(new Vector2(-x, y)); f(new Vector2(x, -y)); f(new Vector2(-x, -y)); } } for (x = step.x(); x < hs.x() + epsilon; x += step.x()) { f(new Vector2(x, 0)); f(new Vector2(-x, 0)); } for (y = step.y(); y < hs.y() + epsilon; y += step.y()) { f(new Vector2(0, y)); f(new Vector2(0, -y)); } break; } default: base.get_pattern(f, d, unobstructed); break; } }
public void get_contour(int contour, PatternConsumer f, double resolution) { }
public void get_pattern(PatternConsumer f, Distribution d, bool unobstructed) { throw new InvalidOperationException("can not distribute rays across an infinite surface shape"); }
public void get_base_pattern(PatternConsumer f, Distribution d, bool unobstructed) { const double epsilon = 1e-8; // FIXME use bounding box instead of max radius double tr = max_radius() * d.get_scaling(); double step = tr / d.get_radial_density(); Pattern p = d.get_pattern(); switch (p) { case Pattern.MeridionalDist: { double r = tr; add_pattern_point(Vector2.vector2_0, unobstructed, this, f); for (int i = 0; i < d.get_radial_density(); i++) { add_pattern_point(new Vector2(0, r), unobstructed, this, f); add_pattern_point(new Vector2(0, -r), unobstructed, this, f); r -= step; } break; } case Pattern.SagittalDist: { double r = tr; add_pattern_point(new Vector2(0, 0), unobstructed, this, f); for (int i = 0; i < d.get_radial_density(); i++) { add_pattern_point(new Vector2(r, 0), unobstructed, this, f); add_pattern_point(new Vector2(-r, 0), unobstructed, this, f); r -= step; } break; } case Pattern.CrossDist: { double r = step; add_pattern_point(Vector2.vector2_0, unobstructed, this, f); for (int i = 0; i < d.get_radial_density(); i++) { add_pattern_point(new Vector2(0, r), unobstructed, this, f); add_pattern_point(new Vector2(r, 0), unobstructed, this, f); add_pattern_point(new Vector2(0, -r), unobstructed, this, f); add_pattern_point(new Vector2(-r, 0), unobstructed, this, f); r += step; } break; } case Pattern.RandomDist: { double x, y; for (x = -tr; x < tr; x += step) { double ybound = Math.Sqrt(MathUtils.square(tr) - MathUtils.square(x)); for (y = -ybound; y < ybound; y += step) { add_pattern_point( new Vector2(x + (random.NextDouble() - .5) * step, y + (random.NextDouble() - .5) * step), unobstructed, this, f); } } break; } case Pattern.HexaPolarDist: { add_pattern_point(Vector2.vector2_0, unobstructed, this, f); for (double r = tr; r > epsilon; r -= step) { double astep = (step / r) * (Math.PI / 3); for (double a = 0; a < 2 * Math.PI - epsilon; a += astep) { add_pattern_point(new Vector2(Math.Sin(a) * r, Math.Cos(a) * r), unobstructed, this, f); } } break; } case Pattern.SquareDist: { add_pattern_point(Vector2.vector2_0, unobstructed, this, f); double x, y; for (x = tr; x > epsilon; x -= step) { double ybound = Math.Sqrt(MathUtils.square(tr) - MathUtils.square(x)); for (y = step; y < ybound; y += step) { add_pattern_point(new Vector2(x, y), unobstructed, this, f); add_pattern_point(new Vector2(x, -y), unobstructed, this, f); add_pattern_point(new Vector2(-x, y), unobstructed, this, f); add_pattern_point(new Vector2(-x, -y), unobstructed, this, f); } add_pattern_point(new Vector2(x, 0), unobstructed, this, f); add_pattern_point(new Vector2(-x, 0), unobstructed, this, f); } for (y = step; y < tr + epsilon; y += step) { add_pattern_point(new Vector2(0, y), unobstructed, this, f); add_pattern_point(new Vector2(0, -y), unobstructed, this, f); } break; } case Pattern.DefaultDist: case Pattern.TriangularDist: { const double sqrt_3_2 = 0.86602540378443864676; double x, y; int i = 1; for (x = step * sqrt_3_2; x < tr + epsilon; x += step * sqrt_3_2) { for (y = step / (double)i; y < tr + epsilon; y += step) { double h = MathUtils.Hypot(x, y); if (h > tr) { break; } add_pattern_point(new Vector2(x, y), unobstructed, this, f); add_pattern_point(new Vector2(-x, y), unobstructed, this, f); add_pattern_point(new Vector2(x, -y), unobstructed, this, f); add_pattern_point(new Vector2(-x, -y), unobstructed, this, f); } i ^= 3; } for (y = step / 2.0; y < tr + epsilon; y += step) { add_pattern_point(new Vector2(0, y), unobstructed, this, f); add_pattern_point(new Vector2(0, -y), unobstructed, this, f); } for (x = step * sqrt_3_2; x < tr + epsilon; x += step * sqrt_3_2 * 2.0) { add_pattern_point(new Vector2(x, 0), unobstructed, this, f); add_pattern_point(new Vector2(-x, 0), unobstructed, this, f); } break; } default: throw new InvalidOperationException("distribution pattern not supported for this shape"); } }
public virtual void get_pattern(PatternConsumer f, Distribution d, bool unobstructed) { get_base_pattern(f, d, unobstructed); }
public abstract void get_contour(int contour, PatternConsumer f, double resolution);
public PatternParser(PatternConsumer consumer) : this() { this.consumer = consumer; }
public override void get_pattern(PatternConsumer f, Distribution d, bool unobstructed) { const double epsilon = 1e-8; double xyr = 1.0 / get_xy_ratio(); double tr = get_external_xradius() * d.get_scaling(); bool obstructed = hole && !unobstructed; double hr = obstructed ? get_internal_xradius() * (2.0 - d.get_scaling()) : 0.0; int rdens = (int)Math.Floor((double)d.get_radial_density() - (d.get_radial_density() * (hr / tr))); rdens = Math.Max(1, rdens); double step = (tr - hr) / rdens; Pattern p = d.get_pattern(); switch (p) { case Pattern.MeridionalDist: { if (!obstructed) { f(Vector2.vector2_0); } double bound = obstructed ? hr - epsilon : epsilon; for (double r = tr; r > bound; r -= step) { f(new Vector2(0, r * xyr)); f(new Vector2(0, -r * xyr)); } } break; case Pattern.SagittalDist: { if (!obstructed) { f(Vector2.vector2_0); } double bound = obstructed ? hr - epsilon : epsilon; for (double r = tr; r > bound; r -= step) { f(new Vector2(r, 0)); f(new Vector2(-r, 0)); } } break; case Pattern.CrossDist: { if (!obstructed) { f(Vector2.vector2_0); } double bound = obstructed ? hr - epsilon : epsilon; for (double r = tr; r > bound; r -= step) { f(new Vector2(0, r * xyr)); f(new Vector2(r, 0)); f(new Vector2(0, -r * xyr)); f(new Vector2(-r, 0)); } } break; case Pattern.RandomDist: { if (!obstructed) { f(Vector2.vector2_0); } double bound = obstructed ? hr - epsilon : epsilon; double tr1 = tr / 20.0; for (double r = tr1; r > bound; r -= step) { double astep = (Math.PI / 3) / Math.Ceiling(r / step); // angle for (double a = 0; a < 2 * Math.PI - epsilon; a += astep) { Vector2 v = new Vector2(Math.Sin(a) * r + (random.NextDouble() - .5) * step, Math.Cos(a) * r * xyr + (random.NextDouble() - .5) * step); double h = MathUtils.Hypot(v.x(), v.y() / xyr); if (h < tr && (h > hr || unobstructed)) { f(v); } } } } break; case Pattern.DefaultDist: case Pattern.HexaPolarDist: { if (!obstructed) { f(Vector2.vector2_0); } double bound = obstructed ? hr - epsilon : epsilon; for (double r = tr; r > bound; r -= step) { double astep = (Math.PI / 3) / Math.Ceiling(r / step); for (double a = 0; a < 2 * Math.PI - epsilon; a += astep) { f(new Vector2(Math.Sin(a) * r, Math.Cos(a) * r * xyr)); } } } break; default: { PatternConsumer f2 = (Vector2 v) => { // unobstructed pattern must be inside external // radius if (MathUtils.square(v.x()) + MathUtils.square(v.y() / xyr) < MathUtils.square(tr)) { f(v); } }; base.get_pattern(f2, d, unobstructed); break; } } }