Improve PdfRectangle.GetWidthHeight();

Improve and simplify Word's oriented bounding box
This commit is contained in:
BobLd
2020-02-18 14:58:55 +00:00
committed by Eliot Jones
parent 67c5abf2b6
commit 42245d70ca
4 changed files with 58 additions and 47 deletions

View File

@@ -300,11 +300,15 @@
var angleRad = Math.Atan(slope);
var cos = Math.Cos(angleRad);
var sin = Math.Sin(angleRad);
var x0sin = x0 * sin;
var y0sin = y0 * sin;
var x0cos = x0 * cos;
var y0cos = y0 * cos;
var transformation = new TransformationMatrix(
var inverseRotation = new TransformationMatrix(
cos, -sin, 0,
sin, cos, 0,
(1.0 - cos) * x0 - sin * y0, sin * x0 - (1.0 - cos) * y0, 1);
0, 0, 1);
var transformedPoints = letters.SelectMany(r => new[]
{
@@ -312,15 +316,20 @@
r.EndBaseLine,
r.GlyphRectangle.TopLeft,
r.GlyphRectangle.TopRight
}).Distinct().Select(p => transformation.Transform(p));
}).Distinct().Select(p => inverseRotation.Transform(p));
var aabb = new PdfRectangle(transformedPoints.Min(p => p.X),
transformedPoints.Min(p => p.Y),
transformedPoints.Max(p => p.X),
transformedPoints.Max(p => p.Y));
// Rotate back the AABB to obtain to oriented bounding box (OBB)
var rotateBack = new TransformationMatrix(
cos, sin, 0,
-sin, cos, 0,
0, 0, 1);
// Candidates bounding boxes
var obb = transformation.Inverse().Transform(aabb);
var obb = rotateBack.Transform(aabb);
var obb1 = new PdfRectangle(obb.BottomLeft, obb.TopLeft, obb.BottomRight, obb.TopRight);
var obb2 = new PdfRectangle(obb.TopRight, obb.BottomRight, obb.TopLeft, obb.BottomLeft);
var obb3 = new PdfRectangle(obb.BottomRight, obb.BottomLeft, obb.TopRight, obb.TopLeft);
@@ -333,7 +342,7 @@
lastLetter.EndBaseLine.X - firstLetter.StartBaseLine.X) * 180 / Math.PI;
var bbox = obb;
var deltaAngle = Math.Abs(baseLineAngle - angleRad);
var deltaAngle = Math.Abs(baseLineAngle - angleRad * 180 / Math.PI);
double deltaAngle1 = Math.Abs(baseLineAngle - obb1.Rotation);
if (deltaAngle1 < deltaAngle)

View File

@@ -209,19 +209,23 @@
var cos = Math.Cos(angleRad);
var sin = Math.Sin(angleRad);
var transformation = new TransformationMatrix(
var inverseRotation = new TransformationMatrix(
cos, -sin, 0,
sin, cos, 0,
(1.0 - cos) * x0 - sin * y0, sin * x0 - (1.0 - cos) * y0, 1);
0, 0, 1);
var transformedPoints = points.Select(p => transformation.Transform(p)).ToArray();
var transformedPoints = points.Select(p => inverseRotation.Transform(p)).ToArray();
var aabb = new PdfRectangle(transformedPoints.Min(p => p.X),
transformedPoints.Min(p => p.Y),
transformedPoints.Max(p => p.X),
transformedPoints.Max(p => p.Y));
// Rotate back the AABB to obtain to oriented bounding box (OBB)
var obb = transformation.Inverse().Transform(aabb);
var rotateBack = new TransformationMatrix(
cos, sin, 0,
-sin, cos, 0,
0, 0, 1);
var obb = rotateBack.Transform(aabb);
return obb;
}
@@ -717,7 +721,7 @@
private static PdfPoint[] Intersect(PdfPath.BezierCurve bezierCurve, PdfPoint p1, PdfPoint p2)
{
var ts = FindIntersectionT(bezierCurve, p1, p2);
var ts = IntersectT(bezierCurve, p1, p2);
if (ts == null || !ts.Any()) return EmptyArray<PdfPoint>.Instance;
List<PdfPoint> points = new List<PdfPoint>();
@@ -743,21 +747,21 @@
/// Get the t values that are the intersections of the line and the curve.
/// </summary>
/// <returns>List of t values where the <see cref="PdfPath.BezierCurve"/> and the <see cref="PdfLine"/> intersect.</returns>
public static double[] FindIntersectionT(this PdfPath.BezierCurve bezierCurve, PdfLine line)
public static double[] IntersectT(this PdfPath.BezierCurve bezierCurve, PdfLine line)
{
return FindIntersectionT(bezierCurve, line.Point1, line.Point2);
return IntersectT(bezierCurve, line.Point1, line.Point2);
}
/// <summary>
/// Get the t values that are the intersections of the line and the curve.
/// </summary>
/// <returns>List of t values where the <see cref="PdfPath.BezierCurve"/> and the <see cref="PdfPath.Line"/> intersect.</returns>
public static double[] FindIntersectionT(this PdfPath.BezierCurve bezierCurve, PdfPath.Line line)
public static double[] IntersectT(this PdfPath.BezierCurve bezierCurve, PdfPath.Line line)
{
return FindIntersectionT(bezierCurve, line.From, line.To);
return IntersectT(bezierCurve, line.From, line.To);
}
private static double[] FindIntersectionT(PdfPath.BezierCurve bezierCurve, PdfPoint p1, PdfPoint p2)
private static double[] IntersectT(PdfPath.BezierCurve bezierCurve, PdfPoint p1, PdfPoint p2)
{
// if the bounding boxes do not intersect, they cannot intersect
var bezierBbox = bezierCurve.GetBoundingRectangle();