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));
            }
        }
Exemple #2
0
 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());
            }
        }
Exemple #5
0
        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;
            }
        }
Exemple #7
0
 public void get_contour(int contour, PatternConsumer f, double resolution)
 {
 }
Exemple #8
0
 public void get_pattern(PatternConsumer f, Distribution d, bool unobstructed)
 {
     throw new InvalidOperationException("can not distribute rays across an infinite surface shape");
 }
Exemple #9
0
        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");
            }
        }
Exemple #10
0
 public virtual void get_pattern(PatternConsumer f,
                                 Distribution d,
                                 bool unobstructed)
 {
     get_base_pattern(f, d, unobstructed);
 }
Exemple #11
0
 public abstract void get_contour(int contour, PatternConsumer f, double resolution);
Exemple #12
0
 public PatternParser(PatternConsumer consumer) : this()
 {
     this.consumer = consumer;
 }
Exemple #13
0
        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;
            }
            }
        }