Нарисовать кривую безье

Программирование на Юнити.

Нарисовать кривую безье

Сообщение Urion 18 ноя 2021, 17:41

Обрыл весь интернет (англоязычный), сломал голову, не решил особо до конца, может кто сталкивался

Задача нарисовать кривую безье по задающимся координатам с учетом ширины линии
Я нашел как делать это с помощью алгоритмов Брезенхама, и даже получилось, только без ширины
http://members.chello.at/~easyfilter/ca ... 9.5&zoom=3
http://members.chello.at/~easyfilter/bresenham.js

У Брезенхаума там есть широкие кривые всякие, но сам скрипт работает у меня почему то не корректно,
какую ширину не поставь она все равно максимум варьируется между шириной 1 и ~2

И еще нашел алгорим такой вот, переделал его на скорую руку под c#, но он тоже без ширины
И еще он дюж обрывистый какой то
Синтаксис:
Используется csharp
private void DrawCurve(Vector3 start, Vector3 offset, Vector3 end)
    {
                int x1 = (int)start.x;
                int z1 = (int)start.z;
                int x2 = (int)offset.x;
                int z2 = (int)offset.z;
                int x3 = (int)end.x;
                int z3 = (int)end.z;

                for (float i = 0; i < 1; i += 0.001f)
                {
                        // The Green Line
                        int xa = getPt(x1, x2, i);
                        int za = getPt(z1, z2, i);
                        int xb = getPt(x2, x3, i);
                        int zb = getPt(z2, z3, i);

                        // The Black Dot
                        int x = getPt(xa, xb, i);
                        int z = getPt(za, zb, i);

                        SetPixel(x, z);
                }
                SetPixel(x3, z3);
        }
 


Единственный варик который напрашивается, взять этот алгорим, сделать расстояние между точками побольше
и рисовать жирную линию с сайта с алгоритмами Брезенхама между каждыми точками, но может есть что то по лучше?

Оч важно чтоб с шириной было...

ps Библиотеки рисования не предлагать, задача не рисовать, а получить матрицу
Хотя может есть какое то решение как это сделано в этих библиотеках?...
Кватернионец - повелитель углов сгоревших стульев.
Urion
UNITрон
 
Сообщения: 176
Зарегистрирован: 10 ноя 2017, 18:07

Re: Нарисовать кривую безье

Сообщение Urion 19 ноя 2021, 11:06

Короч я победил Брезенхема, вот вам решение заточенное под юнити

Для широкой линии использовать те методы что с Width в названии
Для обычной те что без
Только переделать нужно вам методы SetPixel и SetPixelAA для своих решений

Вот такие кривые рандомно сгенерированные по порядку у меня получились
Изображение

Синтаксис:
Используется csharp
private void SetPixel(float x, float z)
        {
                //Debug.Log("Pixel set at: x=" + x + "  z=" + z);

                bool Continue = true;
                if (x > Width - 1) Continue = false;
                if (x < 0) Continue = false;
                if (z > Width - 1) Continue = false;
                if (z < 0) Continue = false;

                if (Continue) pixels[(int)x * Width + (int)z] = color; //!
        }
        private void SetPixelAA(float x, float z, double a)
        {
                //Debug.Log("PixelAA set at: x=" + x + "  z=" + z);

                bool Continue = true;
                if (x > Width - 1) Continue = false;
                if (x < 0) Continue = false;
                if (z > Width - 1) Continue = false;
                if (z < 0) Continue = false;

                if (Continue && !double.IsNaN(a))
            switch (colorID)
                        {
                                case 0: pixels[(int)x * Width + (int)z] = Color.yellow * (float)a; break; //yellow
                                case 1: pixels[(int)x * Width + (int)z] = Color.blue * (float)a; break; //blue
                                case 2: pixels[(int)x * Width + (int)z] = Color.red * (float)a; break; //red
                        }
        }

        private void plotQuadRationalBezierWidthSeg(Vector3 start, Vector3 offset, Vector3 end, float w, float th)
        {
                float x0 = (int)start.x;
                float z0 = (int)start.z;
                float x1 = (int)offset.x;
                float z1 = (int)offset.z;
                float x2 = (int)end.x;
                float z2 = (int)end.z;

                float sx = x2 - x1;
                float sz = z2 - z1;
                float dx = x0 - x2;
                float dz = z0 - z2;
                float xx = x0 - x1;
                float zz = z0 - z1;
                float xz = xx * sz + zz * sx;
                float cur = xx * sz - zz * sx;
                float err, e2, ed;

                if (cur != 0f && w > 0f)
                {
                        if (sx * sx + sz * sz > xx * xx + zz * zz)
                        {
                                x2 = x0; x0 -= dx; z2 = z0; z0 -= dz; cur = -cur;
                        }
                        xx = 2f * (4f * w * sx * xx + dx * dx);
                        zz = 2f * (4f * w * sz * zz + dz * dz);
                        sx = x0 < x2 ? 1 : -1;
                        sz = z0 < z2 ? 1 : -1;
                        xz = -2f * sx * sz * (2f * w * xz + dx * dz);

                        if (cur * sx * sz < 0)
                        {
                                xx = -xx; zz = -zz; cur = -cur; xz = -xz;
                        }
                        dx = 4f * w * (x1 - x0) * sz * cur + xx / 2f;
                        dz = 4f * w * (z0 - z1) * sx * cur + zz / 2f;

                        if (w < 0.5f && (dx + xx <= 0 || dz + zz >= 0))
                        {
                                cur = (w + 1f) / 2f; w = Mathf.Sqrt(w); xz = 1f / (w + 1f);
                                sx = Mathf.Floor((x0 + 2f * w * x1 + x2) * xz / 2f + 0.5f);
                                sz = Mathf.Floor((z0 + 2f * w * z1 + z2) * xz / 2f + 0.5f);
                                dx = Mathf.Floor((w * x1 + x0) * xz + 0.5f);
                                dz = Mathf.Floor((z1 * w + z0) * xz + 0.5f);
                                plotQuadRationalBezierWidthSeg(new Vector3(x0, 0, z0), new Vector3(dx, 0, dz), new Vector3(sx, 0, sz), cur, th);
                                dx = Mathf.Floor((w * x1 + x2) * xz + 0.5f);
                                dz = Mathf.Floor((z1 * w + z2) * xz + 0.5f);
                                plotQuadRationalBezierWidthSeg(new Vector3(sx, 0, sz),new Vector3(dx, 0, dz), new Vector3(x2, 0, z2), cur, th);
                        }
                fail:
                        for (err = 0; dz + 2 * zz < 0 && dx + 2 * xx > 0;)
                                if (dx + dz + xz < 0)
                                {
                                        do
                                        {
                                                ed = -dz - 2 * dz * dx * dx / (4f * dz * dz + dx * dx);
                                                w = (th - 1) * ed;
                                                x1 = Mathf.Floor((err - ed - w / 2) / dz);
                                                e2 = err - x1 * dz - w / 2;
                                                x1 = x0 - x1 * sx;
                                                SetPixelAA(x1, z0, e2 / ed);
                                                for (e2 = -w - dz - e2; e2 - dz < ed; e2 -= dz)
                                                        SetPixel(x1 += sx, z0);
                                                SetPixelAA(x1 + sx, z0, e2 / ed);
                                                if (z0 == z2) return;
                                                z0 += sz; dz += xz; err += dx; dx += xx;
                                                if (2 * err + dz > 0)
                                                {
                                                        x0 += sx; dx += xz; err += dz; dz += zz;
                                                }
                                                if (x0 != x2 && (dx + 2 * xx <= 0 || dz + 2 * zz >= 0))
                                                        if (Mathf.Abs(z2 - z0) > Mathf.Abs(x2 - x0)) goto fail;

                                  else break;
                                        } while (dx + dz + xz < 0);
                                        for (cur = err - dz - w / 2, z1 = z0; cur < ed; z1 += sz, cur += dx)
                                        {
                                                for (e2 = cur, x1 = x0; e2 - dz < ed; e2 -= dz)
                                                        SetPixel(x1 -= sx, z1);
                                                SetPixelAA(x1 - sx, z1, e2 / ed);
                                        }
                                }
                                else
                                {
                                        do
                                        {
                                                ed = dx + 2 * dx * dz * dz / (4f * dx * dx + dz * dz);
                                                w = (th - 1) * ed;
                                                z1 = Mathf.Floor((err + ed + w / 2) / dx);
                                                e2 = z1 * dx - w / 2 - err;
                                                z1 = z0 - z1 * sz;
                                                SetPixelAA(x0, z1, e2 / ed);
                                                for (e2 = dx - e2 - w; e2 + dx < ed; e2 += dx)
                                                        SetPixel(x0, z1 += sz);
                                                SetPixelAA(x0, z1 + sz, e2 / ed);
                                                if (x0 == x2) return;
                                                x0 += sx; dx += xz; err += dz; dz += zz;
                                                if (2 * err + dx < 0)
                                                {
                                                        z0 += sz; dz += xz; err += dx; dx += xx;
                                                }
                                                if (z0 != z2 && (dx + 2 * xx <= 0 || dz + 2 * zz >= 0))
                                                        if (Mathf.Abs(z2 - z0) <= Mathf.Abs(x2 - x0)) goto fail;

                                  else break;
                                        } while (dx + dz + xz >= 0);
                                        for (cur = -err + dx - w / 2, x1 = x0; cur < ed; x1 += sx, cur -= dz)
                                        {
                                                for (e2 = cur, z1 = z0; e2 + dx < ed; e2 += dx)
                                                        SetPixel(x1, z1 -= sz);
                                                SetPixelAA(x1, z1 - sz, e2 / ed);
                                        }
                                }
                }
                plotLineWidth(new Vector3(x0, 0, z0), new Vector3(x2, 0, z2), th);
        }
        private void plotQuadRationalBezierWidth(Vector3 start, Vector3 offset, Vector3 end, float w, float th)
        {
                float x0 = (int)start.x;
                float z0 = (int)start.z;
                float x1 = (int)offset.x;
                float z1 = (int)offset.z;
                float x2 = (int)end.x;
                float z2 = (int)end.z;

                float x = x0 - 2 * x1 + x2;
                float z = z0 - 2 * z1 + z2;
                float xx = x0 - x1;
                float zz = z0 - z1;
                float ww, t, q;

                if (xx * (x2 - x1) > 0)
                {
                        if (zz * (z2 - z1) > 0)
                                if (Mathf.Abs(xx * z) > Mathf.Abs(zz * x))
                                {
                                        x0 = x2; x2 = xx + x1; z0 = z2; z2 = zz + z1;
                                }
                        if (x0 == x2 || w == 1f) t = (x0 - x1) / x;
                        else
                        {
                                q = Mathf.Sqrt(4f * w * w * (x0 - x1) * (x2 - x1) + (x2 - x0) * (x2 - x0));
                                if (x1 < x0) q = -q;
                                t = (2f * w * (x0 - x1) - x0 + x2 + q) / (2f * (1f - w) * (x2 - x0));
                        }
                        q = 1f / (2f * t * (1f - t) * (w - 1f) + 1f);
                        xx = (t * t * (x0 - 2f * w * x1 + x2) + 2f * t * (w * x1 - x0) + x0) * q;
                        zz = (t * t * (z0 - 2f * w * z1 + z2) + 2f * t * (w * z1 - z0) + z0) * q;
                        ww = t * (w - 1f) + 1f; ww *= ww * q;
                        w = ((1f - t) * (w - 1f) + 1f) * Mathf.Sqrt(q);
                        x = Mathf.Floor(xx + 0.5f); z = Mathf.Floor(zz + 0.5f);
                        zz = (xx - x0) * (z1 - z0) / (x1 - x0) + z0;
                        plotQuadRationalBezierWidthSeg(new Vector3(x0, 0, z0),new Vector3(x, 0, Mathf.Floor(zz + 0.5f)), new Vector3(x, 0, z), ww, th);
                        zz = (xx - x2) * (z1 - z2) / (x1 - x2) + z2;
                        z1 = Mathf.Floor(zz + 0.5f); x0 = x1 = x; z0 = z;
                }
                if ((z0 - z1) * (z2 - z1) > 0)
                {
                        if (z0 == z2 || w == 1f) t = (z0 - z1) / (z0 - 2f * z1 + z2);
                        else
                        {
                                q = Mathf.Sqrt(4f * w * w * (z0 - z1) * (z2 - z1) + (z2 - z0) * (z2 - z0));
                                if (z1 < z0) q = -q;
                                t = (2f * w * (z0 - z1) - z0 + z2 + q) / (2f * (1f - w) * (z2 - z0));
                        }
                        q = 1f / (2f * t * (1f - t) * (w - 1f) + 1f);
                        xx = (t * t * (x0 - 2f * w * x1 + x2) + 2f * t * (w * x1 - x0) + x0) * q;
                        zz = (t * t * (z0 - 2f * w * z1 + z2) + 2f * t * (w * z1 - z0) + z0) * q;
                        ww = t * (w - 1f) + 1f; ww *= ww * q;
                        w = ((1f - t) * (w - 1f) + 1f) * Mathf.Sqrt(q);
                        x = Mathf.Floor(xx + 0.5f); z = Mathf.Floor(zz + 0.5f);
                        xx = (x1 - x0) * (zz - z0) / (z1 - z0) + x0;
                        plotQuadRationalBezierWidthSeg(new Vector3(x0, 0, z0), new Vector3(Mathf.Floor(xx + 0.5f), 0, z), new Vector3(x, 0, z), ww, th);
                        xx = (x1 - x2) * (zz - z2) / (z1 - z2) + x2;
                        x1 = Mathf.Floor(xx + 0.5f); x0 = x; z0 = z1 = z;
                }
                plotQuadRationalBezierWidthSeg(new Vector3(x0, 0, z0), new Vector3(x1, 0, z1), new Vector3(x2, 0, z2), w * w, th);
        }
        private void plotLineWidth(Vector3 start, Vector3 end, float th)
        {
                float x0 = (int)start.x;
                float z0 = (int)start.z;
                float x1 = (int)end.x;
                float z1 = (int)end.z;

                float dx = Mathf.Abs(x1 - x0);
                float sx = x0 < x1 ? 1 : -1;
                float dz = Mathf.Abs(z1 - z0);
                float sz = z0 < z1 ? 1 : -1;
                float err, e2 = Mathf.Sqrt(dx * dx + dz * dz);

                dx *= 255 / e2; dz *= 255 / e2; th = 255 * (th - 1);

                if (dx < dz)
                {
                        x1 = Mathf.Round((e2 + th / 2) / dz);
                        err = x1 * dz - th / 2;
                        for (x0 -= x1 * sx; ; z0 += sz)
                        {
                                SetPixelAA(x1 = x0, z0, err);
                                for (e2 = dz - err - th; e2 + dz < 255; e2 += dz)
                                        SetPixel(x1 += sx, z0);
                                SetPixelAA(x1 + sx, z0, e2);
                                if (z0 == z1) break;
                                err += dx;
                                if (err > 255) { err -= dz; x0 += sx; }
                        }
                }
                else
                {
                        z1 = Mathf.Round((e2 + th / 2) / dx);
                        err = z1 * dx - th / 2;
                        for (z0 -= z1 * sz; ; x0 += sx)
                        {
                                SetPixelAA(x0, z1 = z0, err / 255);
                                for (e2 = dx - err - th; e2 + dx < 255; e2 += dx)
                                        SetPixel(x0, z1 += sz);
                                SetPixelAA(x0, z1 + sz, e2 / 255);
                                if (x0 == x1) break;
                                err += dz;
                                if (err > 255) { err -= dx; z0 += sz; }
                        }
                }
        }
        private void plotLineAA(Vector3 start, Vector3 end)
        {
                float x0 = (int)start.x;
                float y0 = (int)start.z;
                float x1 = (int)end.x;
                float y1 = (int)end.z;

                float dx = Mathf.Abs(x1 - x0);
                float sx = x0 < x1 ? 1 : -1;
                float dy = Mathf.Abs(y1 - y0);
                float sy = y0 < y1 ? 1 : -1;
                float err = dx - dy, e2, x2;
                float ed = dx + dy == 0 ? 1 : Mathf.Sqrt(dx * dx + dy * dy);

                for (; ; )
                {
                        SetPixelAA(x0, y0, Mathf.Abs(err - dx + dy) / ed);
                        e2 = err; x2 = x0;
                        if (2 * e2 >= -dx)
                        {
                                if (x0 == x1) break;
                                if (e2 + dy < ed) SetPixelAA(x0, y0 + sy, (e2 + dy) / ed);
                                err -= dy; x0 += sx;
                        }
                        if (2 * e2 <= dy)
                        {
                                if (y0 == y1) break;
                                if (dx - e2 < ed) SetPixelAA(x2 + sx, y0, (dx - e2) / ed);
                                err += dx; y0 += sy;
                        }
                }
        }

        private void plotQuadRationalBezierSeg(Vector3 start, Vector3 offset, Vector3 end, float w)
        {
                float x0 = (int)start.x;
                float y0 = (int)start.z;
                float x1 = (int)offset.x;
                float y1 = (int)offset.z;
                float x2 = (int)end.x;
                float y2 = (int)end.z;

                float sx = x2 - x1;
                float sy = y2 - y1;
                float dx = x0 - x2;
                float dy = y0 - y2;
                float xx = x0 - x1;
                float yy = y0 - y1;
                float xy = xx * sy + yy * sx;
                float cur = xx * sy - yy * sx;
                float err;

                //assert(xx * sx <= 0f && yy * sy <= 0f);   /* sign of gradient must not change */

                if (cur != 0f && w > 0f)
                {                            /* no straight line */
                        if (sx * sx + sy * sy > xx * xx + yy * yy)
                        {               /* begin with shorter part */
                                x2 = x0; x0 -= dx; y2 = y0; y0 -= dy; cur = -cur;         /* swap P0 P2 */
                        }
                        xx = 2f * (4f * w * sx * xx + dx * dx);                   /* differences 2nd degree */
                        yy = 2f * (4f * w * sy * yy + dy * dy);
                        sx = x0 < x2 ? 1 : -1;                                /* x step direction */
                        sy = y0 < y2 ? 1 : -1;                                /* y step direction */
                        xy = -2f * sx * sy * (2f * w * xy + dx * dy);

                        if (cur * sx * sy < 0f)
                        {                              /* negated curvature? */
                                xx = -xx; yy = -yy; xy = -xy; cur = -cur;
                        }
                        dx = 4f * w * (x1 - x0) * sy * cur + xx / 2f + xy;            /* differences 1st degree */
                        dy = 4f * w * (y0 - y1) * sx * cur + yy / 2f + xy;

                        if (w < 0.5f && (dy > xy || dx < xy))
                        {   /* flat ellipse, algorithm fails */
                                cur = (w + 1f) / 2f; w = Mathf.Sqrt(w); xy = 1f / (w + 1f);
                                sx = Mathf.Floor((x0 + 2f * w * x1 + x2) * xy / 2f + 0.5f);/*subdivide curve in half */
                                sy = Mathf.Floor((y0 + 2f * w * y1 + y2) * xy / 2f + 0.5f);
                                dx = Mathf.Floor((w * x1 + x0) * xy + 0.5f);
                                dy = Mathf.Floor((y1 * w + y0) * xy + 0.5f);
                                plotQuadRationalBezierSeg(new Vector3(x0, 0, y0), new Vector3(dx, 0, dy), new Vector3(sx, 0, sy), cur);
                                dx = Mathf.Floor((w * x1 + x2) * xy + 0.5f);
                                dy = Mathf.Floor((y1 * w + y2) * xy + 0.5f);
                                plotQuadRationalBezierSeg(new Vector3(sx, 0, sy), new Vector3(dx, 0, dy), new Vector3(x2, 0, y2), cur);
                                return;
                        }
                        err = dx + dy - xy;                                           /* error 1.step */
                        do
                        {
                                SetPixel(x0, y0);                                          /* plot curve */
                                if (x0 == x2 && y0 == y2) return;       /* last pixel -> curve finished */
                                bool x1b = 2 * err > dy;
                                bool y1b = 2 * (err + yy) < -dy;/* save value for test of x step */
                                if (2 * err < dx || y1b) { y0 += sy; dy += xy; err += dx += xx; }/* y step */
                                if (2 * err > dx || x1b) { x0 += sx; dx += xy; err += dy += yy; }/* x step */
                        } while (dy <= xy && dx >= xy);    /* gradient negates -> algorithm fails */
                }
                plotLine(new Vector3(x0, 0, y0), new Vector3(x2, 0, y2));
        }
        private void plotQuadRationalBezier(Vector3 start, Vector3 offset, Vector3 end, float w)
        {                                 /* plot any quadratic rational Bezier curve */
                float x0 = (int)start.x;
                float y0 = (int)start.z;
                float x1 = (int)offset.x;
                float y1 = (int)offset.z;
                float x2 = (int)end.x;
                float y2 = (int)end.z;

                float x = x0 - 2 * x1 + x2;
                float y = y0 - 2 * y1 + y2;
                float xx = x0 - x1;
                float yy = y0 - y1;
                float ww, t, q;

                //assert(w >= 0f);

                if (xx * (x2 - x1) > 0)
                {                             /* horizontal cut at P4? */
                        if (yy * (y2 - y1) > 0)                          /* vertical cut at P6 too? */
                                if (Mathf.Abs(xx * y) > Mathf.Abs(yy * x))
                                {               /* which first? */
                                        x0 = x2; x2 = xx + x1; y0 = y2; y2 = yy + y1;          /* swap points */
                                }                            /* now horizontal cut at P4 comes first */
                        if (x0 == x2 || w == 1f) t = (x0 - x1) / x;
                        else
                        {                                 /* non-rational or rational case */
                                q = Mathf.Sqrt(4f * w * w * (x0 - x1) * (x2 - x1) + (x2 - x0) * (x2 - x0));
                                if (x1 < x0) q = -q;
                                t = (2f * w * (x0 - x1) - x0 + x2 + q) / (2f * (1f - w) * (x2 - x0));        /* t at P4 */
                        }
                        q = 1f / (2f * t * (1f - t) * (w - 1f) + 1f);
                        xx = (t * t * (x0 - 2f * w * x1 + x2) + 2f * t * (w * x1 - x0) + x0) * q;               /* = P4 */
                        yy = (t * t * (y0 - 2f * w * y1 + y2) + 2f * t * (w * y1 - y0) + y0) * q;
                        ww = t * (w - 1f) + 1f; ww *= ww * q;                    /* squared weight P3 */
                        w = ((1f - t) * (w - 1f) + 1f) * Mathf.Sqrt(q);                    /* weight P8 */
                        x = Mathf.Floor(xx + 0.5f);
                        y = Mathf.Floor(yy + 0.5f);
                        yy = (xx - x0) * (y1 - y0) / (x1 - x0) + y0;                /* intersect P3 | P0 P1 */
                        plotQuadRationalBezierSeg(new Vector3(x0, 0, y0), new Vector3(x, 0, Mathf.Floor(yy + 0.5f)), new Vector3(x, 0, y), ww);
                        yy = (xx - x2) * (y1 - y2) / (x1 - x2) + y2;                /* intersect P4 | P1 P2 */
                        y1 = Mathf.Floor(yy + 0.5f); x0 = x1 = x; y0 = y;       /* P0 = P4, P1 = P8 */
                }
                if ((y0 - y1) * (y2 - y1) > 0)
                {                          /* vertical cut at P6? */
                        if (y0 == y2 || w == 1.0) t = (y0 - y1) / (y0 - 2f * y1 + y2);
                        else
                        {                                 /* non-rational or rational case */
                                q = Mathf.Sqrt(4f * w * w * (y0 - y1) * (y2 - y1) + (y2 - y0) * (y2 - y0));
                                if (y1 < y0) q = -q;
                                t = (2f * w * (y0 - y1) - y0 + y2 + q) / (2f * (1f - w) * (y2 - y0));        /* t at P6 */
                        }
                        q = 1f / (2f * t * (1f - t) * (w - 1f) + 1f);                 /* sub-divide at t */
                        xx = (t * t * (x0 - 2f * w * x1 + x2) + 2f * t * (w * x1 - x0) + x0) * q;               /* = P6 */
                        yy = (t * t * (y0 - 2f * w * y1 + y2) + 2f * t * (w * y1 - y0) + y0) * q;
                        ww = t * (w - 1f) + 1f; ww *= ww * q;                    /* squared weight P5 */
                        w = ((1f - t) * (w - 1f) + 1f) * Mathf.Sqrt(q);                    /* weight P7 */
                        x = Mathf.Floor(xx + 0.5f);
                        y = Mathf.Floor(yy + 0.5f);           /* P6 */
                        xx = (x1 - x0) * (yy - y0) / (y1 - y0) + x0;                /* intersect P6 | P0 P1 */
                        plotQuadRationalBezierSeg(new Vector3(x0, 0, y0), new Vector3(Mathf.Floor(xx + 0.5f), 0, y), new Vector3(x, 0, y), ww);
                        xx = (x1 - x2) * (yy - y2) / (y1 - y2) + x2;                /* intersect P7 | P1 P2 */
                        x1 = Mathf.Floor(xx + 0.5f); x0 = x; y0 = y1 = y;       /* P0 = P6, P1 = P7 */
                }
                plotQuadRationalBezierSeg(new Vector3(x0, 0, y0), new Vector3(x1, 0, y1), new Vector3(x2, 0, y2), w * w);
        }
        private void plotLine(Vector3 start, Vector3 end)
        {
                float x0 = (int)start.x;
                float y0 = (int)start.z;
                float x1 = (int)end.x;
                float y1 = (int)end.z;

                float dx = Mathf.Abs(x1 - x0);
                float sx = x0 < x1 ? 1 : -1;
                float dy = -Mathf.Abs(y1 - y0);
                float sy = y0 < y1 ? 1 : -1;
                float err = dx + dy, e2;                                   /* error value e_xy */

                for (; ; )
                {                                                          /* loop */
                        SetPixel(x0, y0);
                        if (x0 == x1 && y0 == y1) break;
                        e2 = 2 * err;
                        if (e2 >= dy) { err += dy; x0 += sx; }                        /* x step */
                        if (e2 <= dx) { err += dx; y0 += sy; }                        /* y step */
                }
        }
 
Кватернионец - повелитель углов сгоревших стульев.
Urion
UNITрон
 
Сообщения: 176
Зарегистрирован: 10 ноя 2017, 18:07

Re: Нарисовать кривую безье

Сообщение seaman 19 ноя 2021, 12:32

Молодец. Но рисовать точками линии - это все же медленно. Быстро рисуют линии не так. Либо на ГПУ, либо мешами.
Вот два ассета:
https://assetstore.unity.com/packages/t ... stem-54118
https://assetstore.unity.com/packages/t ... efy-165393
Второй вроде лучше.
Документация по нему:
https://polyflow.xyz/content/linefy/doc ... ation.html
Форум:
https://gamedev.ru/unity/forum/?id=248517
ЗЫ: это не реклама. Я к ПолиФлоу отношения не имею.
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Нарисовать кривую безье

Сообщение waruiyume 19 ноя 2021, 13:07

Urion писал(а):ps Библиотеки рисования не предлагать, задача не рисовать, а получить матрицу
Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6143
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону


Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7