コード例 #1
0
        private int AddJoint(int pointIndex, ref JoinSample joinSample, PenWorkspace ws, Buffer <CCVector2> insetBuffer, Buffer <CCVector2> outsetBuffer)
        {
            InsetOutsetCount vioCount = new InsetOutsetCount();

            switch (_pen.LineJoin)
            {
            case LineJoin.Miter:
                vioCount = _pen.ComputeMiter(ref joinSample, ws);
                break;

            case LineJoin.Bevel:
                vioCount = _pen.ComputeBevel(ref joinSample, ws);
                break;
            }

            if (insetBuffer != null)
            {
                for (int i = 0; i < vioCount.InsetCount; i++)
                {
                    insetBuffer.SetNext(ws.XYInsetBuffer[i]);
                }
            }
            if (outsetBuffer != null)
            {
                for (int i = 0; i < vioCount.OutsetCount; i++)
                {
                    outsetBuffer.SetNext(ws.XYOutsetBuffer[i]);
                }
            }

            return((_strokeType != StrokeType.Outline) ? AddJoint(pointIndex, vioCount, ws) : 0);
        }
コード例 #2
0
ファイル: Pen.cs プロジェクト: DanCope/Orbits
        //internal InsetOutsetCount ComputeBevel (Vector2 a, Vector2 b, Vector2 c, PenWorkspace ws)
        internal InsetOutsetCount ComputeBevel(ref JoinSample js, PenWorkspace ws)
        {
            Vector2 a = js.PointA;
            Vector2 b = js.PointB;
            Vector2 c = js.PointC;

            Vector2 edgeBA = new Vector2(a.X - b.X, a.Y - b.Y);
            Vector2 edgeBC = new Vector2(c.X - b.X, c.Y - b.Y);
            double  dot    = Vector2.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));
                }
            }

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

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

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

            Vector2 pointA = a;
            Vector2 pointC = c;

            short vertexCount = 0;

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

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

                    vertexCount = 2;
                    break;

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

                    vertexCount = 2;
                    break;

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

                    ws.XYInsetBuffer[0] = b;

                    vertexCount = 1;
                    break;
                }

                Vector2 point5;

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

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

                ws.XYOutsetBuffer[0] = point5;

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

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

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

                    vertexCount = 2;
                    break;

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

                    ws.XYOutsetBuffer[0] = b;

                    vertexCount = 1;
                    break;

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

                    vertexCount = 2;
                    break;
                }

                Vector2 point0;

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

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

                ws.XYInsetBuffer[0] = point0;

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

                return(new InsetOutsetCount(1, vertexCount, true));
            }
        }
コード例 #3
0
ファイル: Pen.cs プロジェクト: DanCope/Orbits
        //internal InsetOutsetCount ComputeMiter (Vector2 a, Vector2 b, Vector2 c, PenWorkspace ws)
        internal InsetOutsetCount ComputeMiter(ref JoinSample js, PenWorkspace ws)
        {
            Vector2 a = js.PointA;
            Vector2 b = js.PointB;
            Vector2 c = js.PointC;

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

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

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

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

            Vector2 point1, point2, point3, point4;

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

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

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

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

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

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

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

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

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

            Vector2 point0, point5;

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

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

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

                point0 = new Vector2(point2.X + t0 * edgeAB.X, point2.Y + t0 * edgeAB.Y);
                point5 = new Vector2(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 Vector2(0, js.LengthB);
            ws.UVOutsetBuffer[0] = new Vector2(1, js.LengthB);

            return(new InsetOutsetCount(1, 1));
        }
コード例 #4
0
        private void CompileClosedPath(IList <CCVector2> points, IList <float> accumLengths, int offset, int count, Pen outlinePen)
        {
            if (_strokeType != StrokeType.Outline)
            {
                InitializeBuffers(count + 1);
            }

            if (IsClose(points[offset], points[offset + count - 1]))
            {
                count--;
            }

            IList <float> lengths = accumLengths ?? _zeroList;

            Buffer <CCVector2> insetBuffer  = null;
            Buffer <CCVector2> outsetBuffer = null;

            if (outlinePen != null && _strokeType != StrokeType.Fill)
            {
                insetBuffer = Pools <Buffer <CCVector2> > .Obtain();

                outsetBuffer = Pools <Buffer <CCVector2> > .Obtain();

                int vCount = _positionData != null ? _positionData.Length : _pen.MaximumVertexCount(count);

                insetBuffer.EnsureCapacity(vCount);
                outsetBuffer.EnsureCapacity(vCount);
            }

            PenWorkspace ws = Pools <PenWorkspace> .Obtain();

            ws.ResetWorkspace(_pen);

            JoinSample joinSample = new JoinSample(points[offset + count - 1], points[offset + 0], points[offset + 1], 0, lengths[offset + 0], lengths[offset + 1]);

            int vBaseIndex = _vertexBufferIndex;
            int vBaseCount = AddJoint(0, ref joinSample, ws, insetBuffer, outsetBuffer);

            int vPrevCount = 0;
            int vNextCount = vBaseCount;

            for (int i = 0; i < count - 2; i++)
            {
                joinSample.Advance(points[offset + i + 2], lengths[offset + i + 2]);

                vPrevCount = vNextCount;
                vNextCount = AddJoint(i + 1, ref joinSample, ws, insetBuffer, outsetBuffer);
                if (_strokeType != StrokeType.Outline)
                {
                    AddSegment(_vertexBufferIndex - vNextCount - vPrevCount, vPrevCount, _jointCCW[i], _vertexBufferIndex - vNextCount, vNextCount, _jointCCW[i + 1]);
                }
            }

            joinSample.Advance(points[offset + 0], lengths[offset + 0]);

            vPrevCount = vNextCount;
            vNextCount = AddJoint(count - 1, ref joinSample, ws, insetBuffer, outsetBuffer);

            if (_strokeType != StrokeType.Outline)
            {
                AddSegment(_vertexBufferIndex - vNextCount - vPrevCount, vPrevCount, _jointCCW[count - 2], _vertexBufferIndex - vNextCount, vNextCount, _jointCCW[count - 1]);
                AddSegment(_vertexBufferIndex - vNextCount, vNextCount, _jointCCW[count - 1], vBaseIndex, vBaseCount, _jointCCW[0]);
            }

            Pools <PenWorkspace> .Release(ws);

            if (outlinePen != null && _strokeType != StrokeType.Fill)
            {
                Array.Reverse(insetBuffer.Data, 0, insetBuffer.Index);

                _outlinePaths = new GraphicsPath[] {
                    new GraphicsPath(outlinePen, insetBuffer.Data, PathType.Closed, 0, insetBuffer.Index),
                    new GraphicsPath(outlinePen, outsetBuffer.Data, PathType.Closed, 0, outsetBuffer.Index),
                };

                Pools <Buffer <CCVector2> > .Release(insetBuffer);

                Pools <Buffer <CCVector2> > .Release(outsetBuffer);
            }
        }
コード例 #5
0
        private void CompileOpenPath(IList <CCVector2> points, IList <float> accumLengths, int offset, int count, Pen outlinePen)
        {
            if (_strokeType != StrokeType.Outline)
            {
                InitializeBuffers(count);
            }

            IList <float> lengths = accumLengths ?? _zeroList;

            Buffer <CCVector2> insetBuffer  = null;
            Buffer <CCVector2> outsetBuffer = null;

            if (outlinePen != null && _strokeType != StrokeType.Fill)
            {
                insetBuffer = Pools <Buffer <CCVector2> > .Obtain();

                outsetBuffer = Pools <Buffer <CCVector2> > .Obtain();

                int vCount = _positionData != null ? _positionData.Length : _pen.MaximumVertexCount(count);

                insetBuffer.EnsureCapacity(vCount);
                outsetBuffer.EnsureCapacity(vCount);
            }

            PenWorkspace ws = Pools <PenWorkspace> .Obtain();

            ws.ResetWorkspace(_pen);
            ws.PathLength = lengths[offset + count - 1];

            int vPrevCount = 0;
            int vNextCount = AddStartPoint(0, points[offset + 0], points[offset + 1], ws, insetBuffer);

            if (insetBuffer != null)
            {
                Array.Reverse(insetBuffer.Data, 0, insetBuffer.Index);
            }

            JoinSample joinSample = new JoinSample(CCVector2.Zero, points[offset + 0], points[offset + 1], 0, lengths[offset + 0], lengths[offset + 1]);

            for (int i = 0; i < count - 2; i++)
            {
                joinSample.Advance(points[offset + i + 2], lengths[offset + i + 2]);

                vPrevCount = vNextCount;
                vNextCount = AddJoint(i + 1, ref joinSample, ws, insetBuffer, outsetBuffer);
                if (_strokeType != StrokeType.Outline)
                {
                    AddSegment(_vertexBufferIndex - vNextCount - vPrevCount, vPrevCount, _jointCCW[i], _vertexBufferIndex - vNextCount, vNextCount, _jointCCW[i + 1]);
                }
            }

            /*for (int i = 0; i < count - 2; i++) {
             *  int i0 = offset + i;
             *  int i1 = i0 + 1;
             *  int i2 = i0 + 2;
             *
             *  vPrevCount = vNextCount;
             *  vNextCount = AddJoint(i + 1, points[i0], points[i1], points[i2], lengths[i0], lengths[i1], lengths[i2], ws, insetBuffer, outsetBuffer);
             *  if (_strokeType != StrokeType.Outline)
             *      AddSegment(_vertexBufferIndex - vNextCount - vPrevCount, vPrevCount, _jointCCW[i], _vertexBufferIndex - vNextCount, vNextCount, _jointCCW[i + 1]);
             * }*/

            vPrevCount = vNextCount;
            vNextCount = AddEndPoint(count - 1, points[offset + count - 2], points[offset + count - 1], ws, insetBuffer);
            if (_strokeType != StrokeType.Outline)
            {
                AddSegment(_vertexBufferIndex - vNextCount - vPrevCount, vPrevCount, _jointCCW[count - 2], _vertexBufferIndex - vNextCount, vNextCount, _jointCCW[count - 1]);
            }

            if (insetBuffer != null)
            {
                Array.Reverse(insetBuffer.Data, 0, insetBuffer.Index);
            }

            Pools <PenWorkspace> .Release(ws);

            if (outlinePen != null && _strokeType != StrokeType.Fill)
            {
                Buffer <CCVector2> mergedBuffer = Pools <Buffer <CCVector2> > .Obtain();

                mergedBuffer.EnsureCapacity(insetBuffer.Index + outsetBuffer.Index);

                Array.Copy(insetBuffer.Data, 0, mergedBuffer.Data, 0, insetBuffer.Index);
                Array.Copy(outsetBuffer.Data, 0, mergedBuffer.Data, insetBuffer.Index, outsetBuffer.Index);

                _outlinePaths = new GraphicsPath[] {
                    new GraphicsPath(outlinePen, mergedBuffer.Data, PathType.Closed, 0, insetBuffer.Index + outsetBuffer.Index),
                };

                Pools <Buffer <CCVector2> > .Release(mergedBuffer);

                Pools <Buffer <CCVector2> > .Release(insetBuffer);

                Pools <Buffer <CCVector2> > .Release(outsetBuffer);
            }
        }