예제 #1
0
        public static int stbtt__solve_cubic(float a, float b, float c, float *r)
        {
            float s  = -a / 3;
            float p  = b - a * a / 3;
            float q  = a * (2 * a * a - 9 * b) / 27 + c;
            float p3 = p * p * p;
            float d  = q * q + 4 * p3 / 27;

            if ((d) >= (0))
            {
                float z = (float)(CRuntime.Sqrt(d));
                float u = (-q + z) / 2;
                float v = (-q - z) / 2;
                u    = stbtt__cuberoot(u);
                v    = stbtt__cuberoot(v);
                r[0] = s + u + v;
                return(1);
            }
            else
            {
                float u = (float)(CRuntime.Sqrt(-p / 3));
                float v = (float)(CRuntime.Acos(-CRuntime.Sqrt(-27 / p3) * q / 2)) / 3;
                float m = (float)(CRuntime.Cos(v));
                float n = (float)(CRuntime.Cos(v - 3.141592 / 2)) * 1.732050808f;
                r[0] = s + u * 2 * m;
                r[1] = s - u * (m + n);
                r[2] = s - u * (m - n);
                return(3);
            }
        }
예제 #2
0
        public static void stbtt__tesselate_cubic(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float objspace_flatness_squared, int n)
        {
            float dx0              = x1 - x0;
            float dy0              = y1 - y0;
            float dx1              = x2 - x1;
            float dy1              = y2 - y1;
            float dx2              = x3 - x2;
            float dy2              = y3 - y2;
            float dx               = x3 - x0;
            float dy               = y3 - y0;
            float longlen          = (float)(CRuntime.Sqrt(dx0 * dx0 + dy0 * dy0) + CRuntime.Sqrt(dx1 * dx1 + dy1 * dy1) + CRuntime.Sqrt(dx2 * dx2 + dy2 * dy2));
            float shortlen         = (float)(CRuntime.Sqrt(dx * dx + dy * dy));
            float flatness_squared = longlen * longlen - shortlen * shortlen;

            if ((n) > (16))
            {
                return;
            }
            if ((flatness_squared) > (objspace_flatness_squared))
            {
                float x01 = (x0 + x1) / 2;
                float y01 = (y0 + y1) / 2;
                float x12 = (x1 + x2) / 2;
                float y12 = (y1 + y2) / 2;
                float x23 = (x2 + x3) / 2;
                float y23 = (y2 + y3) / 2;
                float xa  = (x01 + x12) / 2;
                float ya  = (y01 + y12) / 2;
                float xb  = (x12 + x23) / 2;
                float yb  = (y12 + y23) / 2;
                float mx  = (xa + xb) / 2;
                float my  = (ya + yb) / 2;
                stbtt__tesselate_cubic(points, num_points, x0, y0, x01, y01, xa, ya, mx, my, objspace_flatness_squared, n + 1);
                stbtt__tesselate_cubic(points, num_points, mx, my, xb, yb, x23, y23, x3, y3, objspace_flatness_squared, n + 1);
            }
            else
            {
                stbtt__add_point(points, *num_points, x3, y3);
                *num_points = *num_points + 1;
            }
        }
예제 #3
0
        public static int stbtt__ray_intersect_bezier(float *orig, float *ray, float *q0, float *q1, float *q2, float *hits)
        {
            float q0perp = q0[1] * ray[0] - q0[0] * ray[1];
            float q1perp = q1[1] * ray[0] - q1[0] * ray[1];
            float q2perp = q2[1] * ray[0] - q2[0] * ray[1];
            float roperp = orig[1] * ray[0] - orig[0] * ray[1];
            float a      = q0perp - 2 * q1perp + q2perp;
            float b      = q1perp - q0perp;
            float c      = q0perp - roperp;
            float s0     = 0;
            float s1     = 0;
            int   num_s  = 0;

            if (a != 0.0)
            {
                float discr = b * b - a * c;
                if ((discr) > (0.0))
                {
                    float rcpna = -1 / a;
                    float d     = (float)(CRuntime.Sqrt(discr));
                    s0 = (b + d) * rcpna;
                    s1 = (b - d) * rcpna;
                    if (((s0) >= (0.0)) && (s0 <= 1.0))
                    {
                        num_s = 1;
                    }
                    if ((((d) > (0.0)) && ((s1) >= (0.0))) && (s1 <= 1.0))
                    {
                        if ((num_s) == (0))
                        {
                            s0 = s1;
                        }
                        ++num_s;
                    }
                }
            }
            else
            {
                s0 = c / (-2 * b);
                if (((s0) >= (0.0)) && (s0 <= 1.0))
                {
                    num_s = 1;
                }
            }

            if ((num_s) == (0))
            {
                return(0);
            }
            else
            {
                float rcp_len2 = 1 / (ray[0] * ray[0] + ray[1] * ray[1]);
                float rayn_x   = ray[0] * rcp_len2;
                float rayn_y   = ray[1] * rcp_len2;
                float q0d      = q0[0] * rayn_x + q0[1] * rayn_y;
                float q1d      = q1[0] * rayn_x + q1[1] * rayn_y;
                float q2d      = q2[0] * rayn_x + q2[1] * rayn_y;
                float rod      = orig[0] * rayn_x + orig[1] * rayn_y;
                float q10d     = q1d - q0d;
                float q20d     = q2d - q0d;
                float q0rd     = q0d - rod;
                hits[0] = q0rd + s0 * (2.0f - 2.0f * s0) * q10d + s0 * s0 * q20d;
                hits[1] = a * s0 + b;
                if ((num_s) > (1))
                {
                    hits[2] = q0rd + s1 * (2.0f - 2.0f * s1) * q10d + s1 * s1 * q20d;
                    hits[3] = a * s1 + b;
                    return(2);
                }
                else
                {
                    return(1);
                }
            }
        }