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; } } }
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); }
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); } } }
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)); }
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)); }
// 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); }