Example #1
0
        static void init_wipcells(
            fd_Outline o,
            fd_WIPCell[] cells)
        {
            float w = o.bbox.max_x - o.bbox.min_x;
            float h = o.bbox.max_y - o.bbox.min_y;

            for (uint y = 0; y < o.cell_count_y; y++)
            {
                for (uint x = 0; x < o.cell_count_x; x++)
                {
                    var bbox = new fd_Rect
                    {
                        min_x = o.bbox.min_x + ((float)x / o.cell_count_x) * w,
                        min_y = o.bbox.min_y + ((float)y / o.cell_count_y) * h,
                        max_x = o.bbox.min_x + ((float)(x + 1) / o.cell_count_x) * w,
                        max_y = o.bbox.min_y + ((float)(y + 1) / o.cell_count_y) * h,
                    };

                    uint i = y * o.cell_count_x + x;
                    cells[i].bbox      = bbox;
                    cells[i].from      = uint.MaxValue;
                    cells[i].to        = uint.MaxValue;
                    cells[i].value     = 0;
                    cells[i].start_len = 0;
                }
            }
        }
Example #2
0
        static bool is_line_segment_intersecting_bbox(fd_Rect bbox, Vector2 p1, Vector2 p2)
        {
            if (is_point_inside_bbox_exclusive(bbox, p1))
            {
                return(true);
            }
            if (is_point_inside_bbox_exclusive(bbox, p2))
            {
                return(true);
            }

            float x_top    = line_horizontal_intersect(bbox.max_y, p1, p2);
            float x_bottom = line_horizontal_intersect(bbox.min_y, p1, p2);
            float y_left   = line_vertical_intersect(bbox.min_x, p1, p2);
            float y_right  = line_vertical_intersect(bbox.max_x, p1, p2);

            var top    = new Vector2(x_top, bbox.max_y);
            var bottom = new Vector2(x_bottom, bbox.min_y);
            var left   = new Vector2(bbox.min_x, y_left);
            var right  = new Vector2(bbox.max_x, y_right);

            if (is_between(x_top, bbox.min_x, bbox.max_x) &&
                is_intersection_in_line_segment(p1, p2, top))
            {
                return(true);
            }

            if (is_between(x_bottom, bbox.min_x, bbox.max_x) &&
                is_intersection_in_line_segment(p1, p2, bottom))
            {
                return(true);
            }

            if (is_between(y_left, bbox.min_y, bbox.max_y) &&
                is_intersection_in_line_segment(p1, p2, left))
            {
                return(true);
            }

            if (is_between(y_right, bbox.min_y, bbox.max_y) &&
                is_intersection_in_line_segment(p1, p2, right))
            {
                return(true);
            }

            return(false);
        }
Example #3
0
        public static void fd_bezier2_bbox(List <Vector2> bezier, int offset, out fd_Rect bbox)
        {
            Vector2[] deriv = new Vector2[2];
            fd_bezier2_derivative(bezier, offset, deriv);

            float tx = deriv[0].X / (deriv[0].X - deriv[1].X);
            float ty = deriv[0].Y / (deriv[0].Y - deriv[1].Y);

            bbox.min_x = Math.Min(bezier[0].X, bezier[2].X);
            bbox.min_y = Math.Min(bezier[0].Y, bezier[2].Y);
            bbox.max_x = Math.Max(bezier[0].X, bezier[2].X);
            bbox.max_y = Math.Max(bezier[0].Y, bezier[2].Y);

            if (0.0f <= tx && tx <= 1.0f)
            {
                float x = bezier2_component(bezier[0].X, bezier[1].X, bezier[2].X, tx);

                if (deriv[0].X < deriv[1].X)
                {
                    bbox.min_x = Math.Min(bbox.min_x, x);
                }
                else
                {
                    bbox.max_x = Math.Max(bbox.max_x, x);
                }
            }

            if (0.0f <= ty && ty <= 1.0f)
            {
                float y = bezier2_component(bezier[0].Y, bezier[1].Y, bezier[2].Y, ty);

                if (deriv[0].Y < deriv[1].Y)
                {
                    bbox.min_y = Math.Min(bbox.min_y, y);
                }
                else
                {
                    bbox.max_y = Math.Max(bbox.max_y, y);
                }
            }
        }
Example #4
0
        public static bool fd_bbox_bezier2_intersect(fd_Rect bbox, List <Vector2> bezier, int offset)
        {
            if (is_point_inside_bbox_exclusive(bbox, bezier[offset + 0]))
            {
                return(true);
            }
            if (is_point_inside_bbox_exclusive(bbox, bezier[offset + 2]))
            {
                return(true);
            }

            var bl = new Vector2(bbox.min_x, bbox.min_y);
            var br = new Vector2(bbox.max_x, bbox.min_y);
            var tl = new Vector2(bbox.min_x, bbox.max_y);
            var tr = new Vector2(bbox.max_x, bbox.max_y);

            return(fd_bezier2_line_is_intersecting(bezier, offset, bl, br) ||
                   fd_bezier2_line_is_intersecting(bezier, offset, br, tr) ||
                   fd_bezier2_line_is_intersecting(bezier, offset, tr, tl) ||
                   fd_bezier2_line_is_intersecting(bezier, offset, tl, bl));
        }
Example #5
0
 static bool is_point_inside_bbox_exclusive(fd_Rect bbox, Vector2 p)
 {
     return(is_between_exclusive(p.X, bbox.min_x, bbox.max_x) && is_between_exclusive(p.Y, bbox.min_y, bbox.max_y));
 }
Example #6
0
        // TODO: optimize
        static bool is_cell_filled(
            fd_Outline o,
            fd_Rect bbox)
        {
            var p = new Vector2
            {
                X = (bbox.max_x + bbox.min_x) / 2.0f,
                Y = (bbox.max_y + bbox.min_y) / 2.0f,
            };

            float mindist = float.MaxValue;
            float v       = float.MaxValue;
            uint  j       = uint.MaxValue;

            var num_of_contours = o.contours.Count;

            for (int contour_index = 0; contour_index < num_of_contours; contour_index++)
            {
                uint contour_begin = o.contours[contour_index].begin;
                uint contour_end   = o.contours[contour_index].end;

                for (int i = (int)contour_begin; i < contour_end; i += 2)
                {
                    var p0 = o.points[i];
                    var p1 = o.points[i + 1];
                    var p2 = o.points[i + 2];

                    float t = Geometry.fd_line_calculate_t(p0, p2, p);

                    Vector2 p02;
                    p02 = Vector2.Lerp(p0, p2, t);

                    float udist = Vector2.Distance(p02, p);

                    if (udist < mindist + 0.0001f)
                    {
                        float d = Geometry.fd_line_signed_distance(p0, p2, p);

                        if (udist >= mindist && i > contour_begin)
                        {
                            float lastd = i == contour_end - 2 && j == contour_begin
                                ? Geometry.fd_line_signed_distance(p0, p2, o.points[(int)(contour_begin + 2)])
                                : Geometry.fd_line_signed_distance(p0, p2, o.points[i - 2]);

                            if (lastd < 0.0)
                            {
                                v = Math.Max(d, v);
                            }
                            else
                            {
                                v = Math.Min(d, v);
                            }
                        }
                        else
                        {
                            v = d;
                        }

                        mindist = Math.Min(mindist, udist);
                        j       = (uint)i;
                    }
                }
            }

            return(v > 0.0f);
        }