public void Calculate (CCVector2 p, CCVector2 edgeAB, PenWorkspace ws, PenAlignment alignment, bool start)
        {
            edgeAB.Normalize();

            // [  eAB.X  -eAB.Y ]
            // [  eAB.Y   eAB.X ]

            float tC = edgeAB.X * _width;
            float tS = edgeAB.Y * _width;

            float tX = p.X;
            float tY = p.Y;

            switch (alignment) {
                case PenAlignment.Center:
                    break;

                case PenAlignment.Inset:
                    if (start) {
                        tX = p.X + (-.5f * tS);
                        tY = p.Y - (-.5f * tC);
                    }
                    else {
                        tX = p.X - (-.5f * tS);
                        tY = p.Y + (-.5f * tC);
                    }
                    break;

                case PenAlignment.Outset:
                    if (start) {
                        tX = p.X + (.5f * tS);
                        tY = p.Y - (.5f * tC);
                    }
                    else {
                        tX = p.X - (.5f * tS);
                        tY = p.Y + (.5f * tC);
                    }
                    break;
            }

            for (int i = 0; i < _xyBuffer.Length; i++)
                ws.XYBuffer[i] = new CCVector2(_xyBuffer[i].X * tC - _xyBuffer[i].Y * tS + tX, _xyBuffer[i].X * tS + _xyBuffer[i].Y * tC + tY);

            for (int i = 0; i < _uvBuffer.Length; i++)
                ws.UVBuffer[i] = _uvBuffer[i];

            for (int i = 0; i < _indexBuffer.Length; i++)
                ws.IndexBuffer[i] = _indexBuffer[i];

            for (int i = 0; i < _outlineBuffer.Length; i++)
                ws.OutlineIndexBuffer[i] = _outlineBuffer[i];

            ws.XYBuffer.Index = _xyBuffer.Length;
            ws.UVBuffer.Index = _uvBuffer.Length;
            ws.IndexBuffer.Index = _indexBuffer.Length;
            ws.OutlineIndexBuffer.Index = _outlineBuffer.Length;
        }
Exemple #2
0
        public void Calculate(CCVector2 p, CCVector2 edgeAB, PenWorkspace ws, PenAlignment alignment, bool start)
        {
            edgeAB.Normalize();

            // [  eAB.X  -eAB.Y ]
            // [  eAB.Y   eAB.X ]

            float tC = edgeAB.X * _width;
            float tS = edgeAB.Y * _width;

            float tX = p.X;
            float tY = p.Y;

            switch (alignment)
            {
            case PenAlignment.Center:
                break;

            case PenAlignment.Inset:
                if (start)
                {
                    tX = p.X + (-.5f * tS);
                    tY = p.Y - (-.5f * tC);
                }
                else
                {
                    tX = p.X - (-.5f * tS);
                    tY = p.Y + (-.5f * tC);
                }
                break;

            case PenAlignment.Outset:
                if (start)
                {
                    tX = p.X + (.5f * tS);
                    tY = p.Y - (.5f * tC);
                }
                else
                {
                    tX = p.X - (.5f * tS);
                    tY = p.Y + (.5f * tC);
                }
                break;
            }

            for (int i = 0; i < _xyBuffer.Length; i++)
            {
                ws.XYBuffer[i] = new CCVector2(_xyBuffer[i].X * tC - _xyBuffer[i].Y * tS + tX, _xyBuffer[i].X * tS + _xyBuffer[i].Y * tC + tY);
            }

            for (int i = 0; i < _uvBuffer.Length; i++)
            {
                ws.UVBuffer[i] = _uvBuffer[i];
            }

            for (int i = 0; i < _indexBuffer.Length; i++)
            {
                ws.IndexBuffer[i] = _indexBuffer[i];
            }

            for (int i = 0; i < _outlineBuffer.Length; i++)
            {
                ws.OutlineIndexBuffer[i] = _outlineBuffer[i];
            }

            ws.XYBuffer.Index           = _xyBuffer.Length;
            ws.UVBuffer.Index           = _uvBuffer.Length;
            ws.IndexBuffer.Index        = _indexBuffer.Length;
            ws.OutlineIndexBuffer.Index = _outlineBuffer.Length;
        }
Exemple #3
0
        //internal InsetOutsetCount ComputeBevel (CCVector2 a, CCVector2 b, CCVector2 c, PenWorkspace ws)
        internal InsetOutsetCount ComputeBevel(ref JoinSample js, PenWorkspace ws)
        {
            CCVector2 a = js.PointA;
            CCVector2 b = js.PointB;
            CCVector2 c = js.PointC;

            CCVector2 edgeBA = new CCVector2(a.X - b.X, a.Y - b.Y);
            CCVector2 edgeBC = new CCVector2(c.X - b.X, c.Y - b.Y);
            double    dot    = CCVector2.Dot(edgeBA, edgeBC);

            if (dot < 0)
            {
                double den  = edgeBA.LengthSquared() * edgeBC.LengthSquared();
                double cos2 = (dot * dot) / den;

                if (cos2 > _joinLimitCos2)
                {
                    return(ComputeMiter(ref js, ws));
                }
            }

            CCVector2 edgeAB = new CCVector2(b.X - a.X, b.Y - a.Y);

            edgeAB.Normalize();
            CCVector2 edgeABt = new CCVector2(-edgeAB.Y, edgeAB.X);

            edgeBC.Normalize();
            CCVector2 edgeBCt = new CCVector2(-edgeBC.Y, edgeBC.X);

            CCVector2 pointA = a;
            CCVector2 pointC = c;

            short vertexCount = 0;

            if (Cross2D(edgeAB, edgeBC) > 0)
            {
                switch (Alignment)
                {
                case PenAlignment.Center:
                    float w2 = Width / 2;
                    pointA = new CCVector2(a.X - w2 * edgeABt.X, a.Y - w2 * edgeABt.Y);
                    pointC = new CCVector2(c.X - w2 * edgeBCt.X, c.Y - w2 * edgeBCt.Y);

                    ws.XYInsetBuffer[0] = new CCVector2(b.X + w2 * edgeABt.X, b.Y + w2 * edgeABt.Y);
                    ws.XYInsetBuffer[1] = new CCVector2(b.X + w2 * edgeBCt.X, b.Y + w2 * edgeBCt.Y);

                    vertexCount = 2;
                    break;

                case PenAlignment.Inset:
                    ws.XYInsetBuffer[0] = new CCVector2(b.X + Width * edgeABt.X, b.Y + Width * edgeABt.Y);
                    ws.XYInsetBuffer[1] = new CCVector2(b.X + Width * edgeBCt.X, b.Y + Width * edgeBCt.Y);

                    vertexCount = 2;
                    break;

                case PenAlignment.Outset:
                    pointA = new CCVector2(a.X - Width * edgeABt.X, a.Y - Width * edgeABt.Y);
                    pointC = new CCVector2(c.X - Width * edgeBCt.X, c.Y - Width * edgeBCt.Y);

                    ws.XYInsetBuffer[0] = b;

                    vertexCount = 1;
                    break;
                }

                CCVector2 point5;

                float tdiv = CCVector2.Dot(edgeBCt, edgeAB);
                if (Math.Abs(tdiv) < 0.0005f)
                {
                    point5 = new CCVector2((pointA.X + pointC.X) / 2, (pointA.Y + pointC.Y) / 2);
                }
                else
                {
                    float offset35 = CCVector2.Dot(edgeBCt, pointC);
                    float t5       = (offset35 - CCVector2.Dot(edgeBCt, pointA)) / tdiv;

                    point5 = new CCVector2(pointA.X + t5 * edgeAB.X, pointA.Y + t5 * edgeAB.Y);
                }

                ws.XYOutsetBuffer[0] = point5;

                ws.UVOutsetBuffer[0] = new CCVector2(1, js.LengthB);
                for (int i = 0; i < vertexCount; i++)
                {
                    ws.UVInsetBuffer[i] = new CCVector2(0, js.LengthB);
                }

                return(new InsetOutsetCount(vertexCount, 1, false));
            }
            else
            {
                switch (Alignment)
                {
                case PenAlignment.Center:
                    float w2 = Width / 2;
                    pointA = new CCVector2(a.X + w2 * edgeABt.X, a.Y + w2 * edgeABt.Y);
                    pointC = new CCVector2(c.X + w2 * edgeBCt.X, c.Y + w2 * edgeBCt.Y);

                    ws.XYOutsetBuffer[0] = new CCVector2(b.X - w2 * edgeABt.X, b.Y - w2 * edgeABt.Y);
                    ws.XYOutsetBuffer[1] = new CCVector2(b.X - w2 * edgeBCt.X, b.Y - w2 * edgeBCt.Y);

                    vertexCount = 2;
                    break;

                case PenAlignment.Inset:
                    pointA = new CCVector2(a.X + Width * edgeABt.X, a.Y + Width * edgeABt.Y);
                    pointC = new CCVector2(c.X + Width * edgeBCt.X, c.Y + Width * edgeBCt.Y);

                    ws.XYOutsetBuffer[0] = b;

                    vertexCount = 1;
                    break;

                case PenAlignment.Outset:
                    ws.XYOutsetBuffer[0] = new CCVector2(b.X - Width * edgeABt.X, b.Y - Width * edgeABt.Y);
                    ws.XYOutsetBuffer[1] = new CCVector2(b.X - Width * edgeBCt.X, b.Y - Width * edgeBCt.Y);

                    vertexCount = 2;
                    break;
                }

                CCVector2 point0;

                float tdiv = CCVector2.Dot(edgeBCt, edgeAB);
                if (Math.Abs(tdiv) < 0.0005f)
                {
                    point0 = new CCVector2((pointA.X + pointC.X) / 2, (pointA.Y + pointC.Y) / 2);
                }
                else
                {
                    float offset01 = CCVector2.Dot(edgeBCt, pointC);
                    float t0       = (offset01 - CCVector2.Dot(edgeBCt, pointA)) / tdiv;

                    point0 = new CCVector2(pointA.X + t0 * edgeAB.X, pointA.Y + t0 * edgeAB.Y);
                }

                ws.XYInsetBuffer[0] = point0;

                ws.UVInsetBuffer[0] = new CCVector2(0, js.LengthB);
                for (int i = 0; i < vertexCount; i++)
                {
                    ws.UVOutsetBuffer[i] = new CCVector2(1, js.LengthB);
                }

                return(new InsetOutsetCount(1, vertexCount, true));
            }
        }
Exemple #4
0
        //internal InsetOutsetCount ComputeMiter (CCVector2 a, CCVector2 b, CCVector2 c, PenWorkspace ws)
        internal InsetOutsetCount ComputeMiter(ref JoinSample js, PenWorkspace ws)
        {
            CCVector2 a = js.PointA;
            CCVector2 b = js.PointB;
            CCVector2 c = js.PointC;

            CCVector2 edgeAB = new CCVector2(b.X - a.X, b.Y - a.Y);

            edgeAB.Normalize();
            CCVector2 edgeABt = new CCVector2(-edgeAB.Y, edgeAB.X);

            CCVector2 edgeBC = new CCVector2(c.X - b.X, c.Y - b.Y);

            edgeBC.Normalize();
            CCVector2 edgeBCt = new CCVector2(-edgeBC.Y, edgeBC.X);

            CCVector2 point1, point2, point3, point4;

            switch (Alignment)
            {
            case PenAlignment.Center:
                float w2 = Width / 2;

                point2 = new CCVector2(a.X + w2 * edgeABt.X, a.Y + w2 * edgeABt.Y);
                point4 = new CCVector2(a.X - w2 * edgeABt.X, a.Y - w2 * edgeABt.Y);

                point1 = new CCVector2(c.X + w2 * edgeBCt.X, c.Y + w2 * edgeBCt.Y);
                point3 = new CCVector2(c.X - w2 * edgeBCt.X, c.Y - w2 * edgeBCt.Y);
                break;

            case PenAlignment.Inset:
                point2 = new CCVector2(a.X + Width * edgeABt.X, a.Y + Width * edgeABt.Y);
                point4 = a;

                point1 = new CCVector2(c.X + Width * edgeBCt.X, c.Y + Width * edgeBCt.Y);
                point3 = c;
                break;

            case PenAlignment.Outset:
                point2 = a;
                point4 = new CCVector2(a.X - Width * edgeABt.X, a.Y - Width * edgeABt.Y);

                point1 = c;
                point3 = new CCVector2(c.X - Width * edgeBCt.X, c.Y - Width * edgeBCt.Y);
                break;

            default:
                point2 = CCVector2.Zero;
                point4 = CCVector2.Zero;

                point1 = CCVector2.Zero;
                point3 = CCVector2.Zero;
                break;
            }

            CCVector2 point0, point5;

            float tdiv = CCVector2.Dot(edgeBCt, edgeAB);

            if (Math.Abs(tdiv) < .0005f)
            {
                point0 = new CCVector2((point2.X + point1.X) / 2, (point2.Y + point1.Y) / 2);
                point5 = new CCVector2((point4.X + point3.X) / 2, (point4.Y + point3.Y) / 2);
            }
            else
            {
                float offset01 = CCVector2.Dot(edgeBCt, point1);
                float t0       = (offset01 - CCVector2.Dot(edgeBCt, point2)) / tdiv;

                float offset35 = CCVector2.Dot(edgeBCt, point3);
                float t5       = (offset35 - CCVector2.Dot(edgeBCt, point4)) / tdiv;

                point0 = new CCVector2(point2.X + t0 * edgeAB.X, point2.Y + t0 * edgeAB.Y);
                point5 = new CCVector2(point4.X + t5 * edgeAB.X, point4.Y + t5 * edgeAB.Y);
            }

            double miterLimit = MiterLimit * Width;

            if ((point0 - point5).LengthSquared() > miterLimit * miterLimit)
            {
                return(ComputeBevel(ref js, ws));
            }

            ws.XYInsetBuffer[0]  = point0;
            ws.XYOutsetBuffer[0] = point5;

            ws.UVInsetBuffer[0]  = new CCVector2(0, js.LengthB);
            ws.UVOutsetBuffer[0] = new CCVector2(1, js.LengthB);

            return(new InsetOutsetCount(1, 1));
        }
Exemple #5
0
        //internal InsetOutsetCount ComputeBevel (CCVector2 a, CCVector2 b, CCVector2 c, PenWorkspace ws)
        internal InsetOutsetCount ComputeBevel (ref JoinSample js, PenWorkspace ws)
        {
            CCVector2 a = js.PointA;
            CCVector2 b = js.PointB;
            CCVector2 c = js.PointC;

            CCVector2 edgeBA = new CCVector2(a.X - b.X, a.Y - b.Y);
            CCVector2 edgeBC = new CCVector2(c.X - b.X, c.Y - b.Y);
            double dot = CCVector2.Dot(edgeBA, edgeBC);
            if (dot < 0) {
                double den = edgeBA.LengthSquared() * edgeBC.LengthSquared();
                double cos2 = (dot * dot) / den;

                if (cos2 > _joinLimitCos2)
                    return ComputeMiter(ref js, ws);
            }

            CCVector2 edgeAB = new CCVector2(b.X - a.X, b.Y - a.Y);
            edgeAB.Normalize();
            CCVector2 edgeABt = new CCVector2(-edgeAB.Y, edgeAB.X);

            edgeBC.Normalize();
            CCVector2 edgeBCt = new CCVector2(-edgeBC.Y, edgeBC.X);

            CCVector2 pointA = a;
            CCVector2 pointC = c;

            short vertexCount = 0;

            if (Cross2D(edgeAB, edgeBC) > 0) {
                switch (Alignment) {
                    case PenAlignment.Center:
                        float w2 = Width / 2;
                        pointA = new CCVector2(a.X - w2 * edgeABt.X, a.Y - w2 * edgeABt.Y);
                        pointC = new CCVector2(c.X - w2 * edgeBCt.X, c.Y - w2 * edgeBCt.Y);

                        ws.XYInsetBuffer[0] = new CCVector2(b.X + w2 * edgeABt.X, b.Y + w2 * edgeABt.Y);
                        ws.XYInsetBuffer[1] = new CCVector2(b.X + w2 * edgeBCt.X, b.Y + w2 * edgeBCt.Y);

                        vertexCount = 2;
                        break;

                    case PenAlignment.Inset:
                        ws.XYInsetBuffer[0] = new CCVector2(b.X + Width * edgeABt.X, b.Y + Width * edgeABt.Y);
                        ws.XYInsetBuffer[1] = new CCVector2(b.X + Width * edgeBCt.X, b.Y + Width * edgeBCt.Y);

                        vertexCount = 2;
                        break;

                    case PenAlignment.Outset:
                        pointA = new CCVector2(a.X - Width * edgeABt.X, a.Y - Width * edgeABt.Y);
                        pointC = new CCVector2(c.X - Width * edgeBCt.X, c.Y - Width * edgeBCt.Y);

                        ws.XYInsetBuffer[0] = b;

                        vertexCount = 1;
                        break;
                }

                CCVector2 point5;

                float tdiv = CCVector2.Dot(edgeBCt, edgeAB);
                if (Math.Abs(tdiv) < 0.0005f) {
                    point5 = new CCVector2((pointA.X + pointC.X) / 2, (pointA.Y + pointC.Y) / 2);
                }
                else {
                    float offset35 = CCVector2.Dot(edgeBCt, pointC);
                    float t5 = (offset35 - CCVector2.Dot(edgeBCt, pointA)) / tdiv;

                    point5 = new CCVector2(pointA.X + t5 * edgeAB.X, pointA.Y + t5 * edgeAB.Y);
                }

                ws.XYOutsetBuffer[0] = point5;

                ws.UVOutsetBuffer[0] = new CCVector2(1, js.LengthB);
                for (int i = 0; i < vertexCount; i++)
                    ws.UVInsetBuffer[i] = new CCVector2(0, js.LengthB);

                return new InsetOutsetCount(vertexCount, 1, false);
            }
            else {
                switch (Alignment) {
                    case PenAlignment.Center:
                        float w2 = Width / 2;
                        pointA = new CCVector2(a.X + w2 * edgeABt.X, a.Y + w2 * edgeABt.Y);
                        pointC = new CCVector2(c.X + w2 * edgeBCt.X, c.Y + w2 * edgeBCt.Y);

                        ws.XYOutsetBuffer[0] = new CCVector2(b.X - w2 * edgeABt.X, b.Y - w2 * edgeABt.Y);
                        ws.XYOutsetBuffer[1] = new CCVector2(b.X - w2 * edgeBCt.X, b.Y - w2 * edgeBCt.Y);

                        vertexCount = 2;
                        break;

                    case PenAlignment.Inset:
                        pointA = new CCVector2(a.X + Width * edgeABt.X, a.Y + Width * edgeABt.Y);
                        pointC = new CCVector2(c.X + Width * edgeBCt.X, c.Y + Width * edgeBCt.Y);

                        ws.XYOutsetBuffer[0] = b;

                        vertexCount = 1;
                        break;

                    case PenAlignment.Outset:
                        ws.XYOutsetBuffer[0] = new CCVector2(b.X - Width * edgeABt.X, b.Y - Width * edgeABt.Y);
                        ws.XYOutsetBuffer[1] = new CCVector2(b.X - Width * edgeBCt.X, b.Y - Width * edgeBCt.Y);

                        vertexCount = 2;
                        break;
                }

                CCVector2 point0;

                float tdiv = CCVector2.Dot(edgeBCt, edgeAB);
                if (Math.Abs(tdiv) < 0.0005f) {
                    point0 = new CCVector2((pointA.X + pointC.X) / 2, (pointA.Y + pointC.Y) / 2);
                }
                else {
                    float offset01 = CCVector2.Dot(edgeBCt, pointC);
                    float t0 = (offset01 - CCVector2.Dot(edgeBCt, pointA)) / tdiv;

                    point0 = new CCVector2(pointA.X + t0 * edgeAB.X, pointA.Y + t0 * edgeAB.Y);
                }

                ws.XYInsetBuffer[0] = point0;

                ws.UVInsetBuffer[0] = new CCVector2(0, js.LengthB);
                for (int i = 0; i < vertexCount; i++)
                    ws.UVOutsetBuffer[i] = new CCVector2(1, js.LengthB);

                return new InsetOutsetCount(1, vertexCount, true);
            }
        }
Exemple #6
0
        //internal InsetOutsetCount ComputeMiter (CCVector2 a, CCVector2 b, CCVector2 c, PenWorkspace ws)
        internal InsetOutsetCount ComputeMiter (ref JoinSample js, PenWorkspace ws)
        {
            CCVector2 a = js.PointA;
            CCVector2 b = js.PointB;
            CCVector2 c = js.PointC;

            CCVector2 edgeAB = new CCVector2(b.X - a.X, b.Y - a.Y);
            edgeAB.Normalize();
            CCVector2 edgeABt = new CCVector2(-edgeAB.Y, edgeAB.X);

            CCVector2 edgeBC = new CCVector2(c.X - b.X, c.Y - b.Y);
            edgeBC.Normalize();
            CCVector2 edgeBCt = new CCVector2(-edgeBC.Y, edgeBC.X);

            CCVector2 point1, point2, point3, point4;

            switch (Alignment) {
                case PenAlignment.Center:
                    float w2 = Width / 2;

                    point2 = new CCVector2(a.X + w2 * edgeABt.X, a.Y + w2 * edgeABt.Y);
                    point4 = new CCVector2(a.X - w2 * edgeABt.X, a.Y - w2 * edgeABt.Y);

                    point1 = new CCVector2(c.X + w2 * edgeBCt.X, c.Y + w2 * edgeBCt.Y);
                    point3 = new CCVector2(c.X - w2 * edgeBCt.X, c.Y - w2 * edgeBCt.Y);
                    break;

                case PenAlignment.Inset:
                    point2 = new CCVector2(a.X + Width * edgeABt.X, a.Y + Width * edgeABt.Y);
                    point4 = a;

                    point1 = new CCVector2(c.X + Width * edgeBCt.X, c.Y + Width * edgeBCt.Y);
                    point3 = c;
                    break;

                case PenAlignment.Outset:
                    point2 = a;
                    point4 = new CCVector2(a.X - Width * edgeABt.X, a.Y - Width * edgeABt.Y);

                    point1 = c;
                    point3 = new CCVector2(c.X - Width * edgeBCt.X, c.Y - Width * edgeBCt.Y);
                    break;

                default:
                    point2 = CCVector2.Zero;
                    point4 = CCVector2.Zero;

                    point1 = CCVector2.Zero;
                    point3 = CCVector2.Zero;
                    break;
            }

            CCVector2 point0, point5;

            float tdiv = CCVector2.Dot(edgeBCt, edgeAB);

            if (Math.Abs(tdiv) < .0005f) {
                point0 = new CCVector2((point2.X + point1.X) / 2, (point2.Y + point1.Y) / 2);
                point5 = new CCVector2((point4.X + point3.X) / 2, (point4.Y + point3.Y) / 2);
            }
            else {
                float offset01 = CCVector2.Dot(edgeBCt, point1);
                float t0 = (offset01 - CCVector2.Dot(edgeBCt, point2)) / tdiv;

                float offset35 = CCVector2.Dot(edgeBCt, point3);
                float t5 = (offset35 - CCVector2.Dot(edgeBCt, point4)) / tdiv;

                point0 = new CCVector2(point2.X + t0 * edgeAB.X, point2.Y + t0 * edgeAB.Y);
                point5 = new CCVector2(point4.X + t5 * edgeAB.X, point4.Y + t5 * edgeAB.Y);
            }

            double miterLimit = MiterLimit * Width;
            if ((point0 - point5).LengthSquared() > miterLimit * miterLimit)
                return ComputeBevel(ref js, ws);

            ws.XYInsetBuffer[0] = point0;
            ws.XYOutsetBuffer[0] = point5;

            ws.UVInsetBuffer[0] = new CCVector2(0, js.LengthB);
            ws.UVOutsetBuffer[0] = new CCVector2(1, js.LengthB);

            return new InsetOutsetCount(1, 1);
        }