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