mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-09-19 19:07:56 +08:00
Improve PdfRectangle.GetWidthHeight();
Improve and simplify Word's oriented bounding box
This commit is contained in:
@@ -86,18 +86,7 @@
|
||||
{
|
||||
get
|
||||
{
|
||||
double t;
|
||||
if (!BottomRight.Equals(BottomLeft))
|
||||
{
|
||||
t = Math.Atan2(BottomRight.Y - BottomLeft.Y, BottomRight.X - BottomLeft.X);
|
||||
}
|
||||
else
|
||||
{
|
||||
// handle the case where both bottom points are identical
|
||||
t = Math.Atan2(TopLeft.Y - BottomLeft.Y, TopLeft.X - BottomLeft.X) - Math.PI / 2;
|
||||
}
|
||||
|
||||
return t * 180 / Math.PI;
|
||||
return GetT() * 180 / Math.PI;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,11 +173,32 @@
|
||||
BottomLeft.Translate(dx, dy), BottomRight.Translate(dx, dy));
|
||||
}
|
||||
|
||||
private double GetT()
|
||||
{
|
||||
if (!BottomRight.Equals(BottomLeft))
|
||||
{
|
||||
return Math.Atan2(BottomRight.Y - BottomLeft.Y, BottomRight.X - BottomLeft.X);
|
||||
}
|
||||
else
|
||||
{
|
||||
// handle the case where both bottom points are identical
|
||||
return Math.Atan2(TopLeft.Y - BottomLeft.Y, TopLeft.X - BottomLeft.X) - Math.PI / 2;
|
||||
}
|
||||
}
|
||||
|
||||
private void GetWidthHeight()
|
||||
{
|
||||
var tm = TransformationMatrix.GetRotationMatrix(Rotation).Inverse();
|
||||
width = tm.Transform(BottomRight).X - tm.Transform(BottomLeft).X;
|
||||
height = tm.Transform(TopLeft).Y - tm.Transform(BottomLeft).Y;
|
||||
var t = GetT();
|
||||
var cos = Math.Cos(t);
|
||||
var sin = Math.Sin(t);
|
||||
|
||||
var inverseRotation = new TransformationMatrix(
|
||||
cos, -sin, 0,
|
||||
sin, cos, 0,
|
||||
0, 0, 1);
|
||||
|
||||
width = inverseRotation.Transform(BottomRight).X - inverseRotation.Transform(BottomLeft).X;
|
||||
height = inverseRotation.Transform(TopLeft).Y - inverseRotation.Transform(BottomLeft).Y;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@@ -90,9 +90,7 @@
|
||||
PdfRectangle rectangle4 = new PdfRectangle(5, 7, 10, 25);
|
||||
Assert.False(rectangle1.IntersectsWith(rectangle4));
|
||||
|
||||
|
||||
PdfRectangle rectangle5 = new PdfRectangle(new PdfPoint(878.2919644480792, 284.98675185325374), new PdfPoint(862.1750371743453, 246.06041964596272), new PdfPoint(674.8837206318682, 369.20521494929005), new PdfPoint(658.7667933581344, 330.2788827419989));
|
||||
|
||||
Assert.False(rectangle5.IntersectsWith(new PdfRectangle(new PdfPoint(353.1968952039725, 430.7443580752997), new PdfPoint(446.46498829172396, 861.3602670280086), new PdfPoint(279.1778049563087, 446.7763235832159), new PdfPoint(372.44589804406013, 877.3922325359247))));
|
||||
Assert.True(rectangle5.IntersectsWith(new PdfRectangle(new PdfPoint(667.0669096951665, 198.51789529471972), new PdfPoint(382.6159639765757, 304.5417365505567), new PdfPoint(805.4174478896282, 569.6980087856942), new PdfPoint(520.9665021710373, 675.7218500415313))));
|
||||
Assert.False(rectangle5.IntersectsWith(new PdfRectangle(new PdfPoint(551.3092120057465, 227.06692642283235), new PdfPoint(573.7600100241283, 224.45067656822854), new PdfPoint(637.1984096402393, 964.1070163284926), new PdfPoint(659.6492076586211, 961.4907664738888))));
|
||||
@@ -108,10 +106,8 @@
|
||||
Assert.False(rectangle5.IntersectsWith(new PdfRectangle(new PdfPoint(589.6127906613359, 428.73052433904), new PdfPoint(590.4285001742446, 450.33962086005704), new PdfPoint(83.55291951467768, 447.83349102689664), new PdfPoint(84.3686290275864, 469.44258754791366))));
|
||||
Assert.False(rectangle5.IntersectsWith(new PdfRectangle(new PdfPoint(527.4319517027001, 713.9214038056743), new PdfPoint(474.4501775934585, 656.9306524140234), new PdfPoint(574.9484349425286, 669.74743662673), new PdfPoint(521.966660833287, 612.7566852350792))));
|
||||
Assert.False(rectangle5.IntersectsWith(new PdfRectangle(new PdfPoint(227.56613088253334, 434.82640067032025), new PdfPoint(302.4286146616149, 238.31257488185557), new PdfPoint(-75.2573302718133, 319.4649681724581), new PdfPoint(-0.39484649273174455, 122.95114238399341))));
|
||||
|
||||
|
||||
|
||||
PdfRectangle rectangle6 = new PdfRectangle(new PdfPoint(662.1090997035524, 32.17519235014163), new PdfPoint(806.0379110211408, 315.93110789147556), new PdfPoint(339.06556720072024, 196.03176446165605), new PdfPoint(482.9943785183086, 479.78768000299));
|
||||
|
||||
Assert.False(rectangle6.IntersectsWith(new PdfRectangle(new PdfPoint(189.05553239397122, 954.3244361250967), new PdfPoint(383.00565538205376, 941.1111183775815), new PdfPoint(153.72614299627176, 435.74616912881055), new PdfPoint(347.67626598435436, 422.5328513812954))));
|
||||
Assert.True(rectangle6.IntersectsWith(new PdfRectangle(new PdfPoint(995.5897815154967, 1.1229217531037676), new PdfPoint(379.34059275027573, 21.64016669347191), new PdfPoint(999.1015392990057, 106.60091802001234), new PdfPoint(382.8523505337847, 127.11816296038049))));
|
||||
Assert.False(rectangle6.IntersectsWith(new PdfRectangle(new PdfPoint(241.11149345040388, 619.9967264825813), new PdfPoint(237.1881211805317, 604.4557261946209), new PdfPoint(226.79603116379286, 623.6107079976066), new PdfPoint(222.8726588939207, 608.0697077096462))));
|
||||
@@ -127,10 +123,8 @@
|
||||
Assert.False(rectangle6.IntersectsWith(new PdfRectangle(new PdfPoint(717.68521670706, 809.7007029409066), new PdfPoint(621.190366829182, 813.5865480300052), new PdfPoint(707.18690874391, 549.0025465172622), new PdfPoint(610.692058866032, 552.8883916063609))));
|
||||
Assert.True(rectangle6.IntersectsWith(new PdfRectangle(new PdfPoint(294.3463877234756, 636.4837934326679), new PdfPoint(689.1715874504388, 198.35020500129144), new PdfPoint(573.8239023166606, 888.3356679112038), new PdfPoint(968.6491020436237, 450.2020794798273))));
|
||||
Assert.False(rectangle6.IntersectsWith(new PdfRectangle(new PdfPoint(523.8760324273468, 59.56931986367704), new PdfPoint(537.4510792959534, 87.35541425053748), new PdfPoint(591.3110514063164, 26.623576194938323), new PdfPoint(604.886098274923, 54.409670581798764))));
|
||||
|
||||
|
||||
|
||||
PdfRectangle rectangle7 = new PdfRectangle(new PdfPoint(182.95967923508024, 378.6167914103907), new PdfPoint(426.47638943669153, 379.5221368891931), new PdfPoint(180.78120599362617, 964.5750244187219), new PdfPoint(424.29791619523746, 965.4803698975243));
|
||||
|
||||
Assert.False(rectangle7.IntersectsWith(new PdfRectangle(new PdfPoint(761.5597778351872, 941.1192604974003), new PdfPoint(633.51933021415, 795.815811545735), new PdfPoint(1137.453093713675, 609.8845322780608), new PdfPoint(1009.4126460926377, 464.5810833263956))));
|
||||
Assert.True(rectangle7.IntersectsWith(new PdfRectangle(new PdfPoint(346.38019022487805, 962.9027155935489), new PdfPoint(958.9455360803695, 469.3068278732299), new PdfPoint(-41.2821063348334, 481.803714011534), new PdfPoint(571.2832395206581, -11.792173708785015))));
|
||||
Assert.False(rectangle7.IntersectsWith(new PdfRectangle(new PdfPoint(944.7329525257767, 570.6504069116083), new PdfPoint(982.5761178272382, 510.51399836788244), new PdfPoint(520.2007288578434, 303.4970549720583), new PdfPoint(558.0438941593047, 243.36064642833253))));
|
||||
@@ -146,10 +140,8 @@
|
||||
Assert.True(rectangle7.IntersectsWith(new PdfRectangle(new PdfPoint(802.8192348116105, 416.2791077053364), new PdfPoint(799.4741400026777, 395.89519632164547), new PdfPoint(322.222983998549, 495.1471911426298), new PdfPoint(318.8778891896162, 474.7632797589389))));
|
||||
Assert.False(rectangle7.IntersectsWith(new PdfRectangle(new PdfPoint(586.2037586388597, 470.8287115308515), new PdfPoint(522.4985869468035, 277.11479640636696), new PdfPoint(606.4591337194657, 464.167485638185), new PdfPoint(542.7539620274097, 270.45357051370047))));
|
||||
Assert.True(rectangle7.IntersectsWith(new PdfRectangle(new PdfPoint(434.6663895248496, 651.5308843669638), new PdfPoint(456.0878643202198, 234.94337283417667), new PdfPoint(246.87900283942474, 641.8746112925039), new PdfPoint(268.3004776347949, 225.28709975971685))));
|
||||
|
||||
|
||||
|
||||
PdfRectangle rectangle8 = new PdfRectangle(new PdfPoint(72.24297257469115, 649.2596478120211), new PdfPoint(775.2698559740438, 649.2596478120211), new PdfPoint(72.24297257469115, 259.0291933094048), new PdfPoint(775.2698559740438, 259.0291933094048));
|
||||
|
||||
Assert.True(rectangle8.IntersectsWith(new PdfRectangle(new PdfPoint(135.73325218195308, 188.61070668538804), new PdfPoint(971.1947687261684, 188.61070668538804), new PdfPoint(135.73325218195308, 980.9459766541829), new PdfPoint(971.1947687261684, 980.9459766541829))));
|
||||
Assert.False(rectangle8.IntersectsWith(new PdfRectangle(new PdfPoint(887.1665126362909, 685.0924487297474), new PdfPoint(361.59633731366625, 685.0924487297474), new PdfPoint(887.1665126362909, 958.0750301074823), new PdfPoint(361.59633731366625, 958.0750301074823))));
|
||||
Assert.False(rectangle8.IntersectsWith(new PdfRectangle(new PdfPoint(94.56638479872082, 36.92587654212054), new PdfPoint(462.6070546281588, 36.92587654212054), new PdfPoint(94.56638479872082, 200.29051698988076), new PdfPoint(462.6070546281588, 200.29051698988076))));
|
||||
@@ -165,10 +157,8 @@
|
||||
Assert.True(rectangle8.IntersectsWith(new PdfRectangle(new PdfPoint(444.2990302895924, 361.35131179733884), new PdfPoint(683.6918159556293, 361.35131179733884), new PdfPoint(444.2990302895924, 371.7479591330548), new PdfPoint(683.6918159556293, 371.7479591330548))));
|
||||
Assert.True(rectangle8.IntersectsWith(new PdfRectangle(new PdfPoint(893.0590924218519, 683.0027652560051), new PdfPoint(738.6303815244727, 683.0027652560051), new PdfPoint(893.0590924218519, 392.96008379091865), new PdfPoint(738.6303815244727, 392.96008379091865))));
|
||||
Assert.True(rectangle8.IntersectsWith(new PdfRectangle(new PdfPoint(876.8447498709081, 105.49457512519412), new PdfPoint(72.8325766734833, 105.49457512519412), new PdfPoint(876.8447498709081, 464.6650759722718), new PdfPoint(72.8325766734833, 464.6650759722718))));
|
||||
|
||||
|
||||
|
||||
PdfRectangle rectangle9 = new PdfRectangle(new PdfPoint(527.2438195115226, 482.9801794154479), new PdfPoint(527.2438195115226, 533.4881831146383), new PdfPoint(768.1236383182934, 482.9801794154479), new PdfPoint(768.1236383182934, 533.4881831146383));
|
||||
|
||||
Assert.True(rectangle9.IntersectsWith(new PdfRectangle(new PdfPoint(896.2540086673047, 50.788729046773454), new PdfPoint(585.7259398610713, 50.788729046773454), new PdfPoint(896.2540086673047, 981.9968313141578), new PdfPoint(585.7259398610713, 981.9968313141578))));
|
||||
Assert.True(rectangle9.IntersectsWith(new PdfRectangle(new PdfPoint(975.4166831750707, 490.84681151603615), new PdfPoint(78.87287902477968, 490.84681151603615), new PdfPoint(975.4166831750707, 388.2081094509828), new PdfPoint(78.87287902477968, 388.2081094509828))));
|
||||
Assert.False(rectangle9.IntersectsWith(new PdfRectangle(new PdfPoint(948.3251791106021, 66.97725486792005), new PdfPoint(873.5802713629491, 66.97725486792005), new PdfPoint(948.3251791106021, 385.08786496108115), new PdfPoint(873.5802713629491, 385.08786496108115))));
|
||||
@@ -184,10 +174,8 @@
|
||||
Assert.False(rectangle9.IntersectsWith(new PdfRectangle(new PdfPoint(17.796763977895647, 355.96614105536116), new PdfPoint(102.82502664462689, 355.96614105536116), new PdfPoint(17.796763977895647, 881.6150247557526), new PdfPoint(102.82502664462689, 881.6150247557526))));
|
||||
Assert.True(rectangle9.IntersectsWith(new PdfRectangle(new PdfPoint(587.2618612142032, 318.14001496409116), new PdfPoint(731.2896862521135, 318.14001496409116), new PdfPoint(587.2618612142032, 696.6383491864503), new PdfPoint(731.2896862521135, 696.6383491864503))));
|
||||
Assert.False(rectangle9.IntersectsWith(new PdfRectangle(new PdfPoint(741.2224344081615, 780.9041501122545), new PdfPoint(99.26197376045431, 780.9041501122545), new PdfPoint(741.2224344081615, 767.463545155378), new PdfPoint(99.26197376045431, 767.463545155378))));
|
||||
|
||||
|
||||
|
||||
PdfRectangle rectangle10 = new PdfRectangle(new PdfPoint(234.60559171191113, 296.83326039714007), new PdfPoint(371.9089402414718, 544.7935633876145), new PdfPoint(724.3131470663056, 25.666923126748543), new PdfPoint(861.6164955958661, 273.627226117223));
|
||||
|
||||
Assert.True(rectangle10.IntersectsWith(new PdfRectangle(new PdfPoint(555.6927483036488, 427.9916727628121), new PdfPoint(577.2339652380674, 484.66031814130065), new PdfPoint(-84.30005120431736, 671.2694790097953), new PdfPoint(-62.7588342698989, 727.9381243882838))));
|
||||
Assert.False(rectangle10.IntersectsWith(new PdfRectangle(new PdfPoint(785.2982960489057, 998.9422662129181), new PdfPoint(538.5359876657087, 525.8777450375484), new PdfPoint(572.5356879132348, 1109.924574061206), new PdfPoint(325.7733795300377, 636.8600528858361))));
|
||||
Assert.True(rectangle10.IntersectsWith(new PdfRectangle(new PdfPoint(497.80599419376176, 373.5540389184093), new PdfPoint(482.9973315724043, 502.2649741422026), new PdfPoint(-94.0991400195588, 305.45319401992487), new PdfPoint(-108.90780264091634, 434.16412924371826))));
|
||||
|
@@ -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)
|
||||
|
@@ -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();
|
||||
|
Reference in New Issue
Block a user