Search code examples
pdflib

PDFlib - rotating objects around center by arbitrary degree


Task: I need to to rotate a square, rectangle or triangle by arbitrary angle around its center as pivot.

PDFlib documentation states that rotation always occurs around object's bottom-left corner.

This is my attempt to rotate a square around its center:

// Gray square positioned before rotation
$p->setcolor('stroke', '#999999', null, null, null, null);
$p->rect(200, 200, 100, 100);
$p->stroke();

// Red square rotated by 45 degrees, around its center as pivot
$p->setcolor('stroke', '#ff0000', null, null, null, null);
$p->save();
$p->translate(200 - 20.71, 200 - 50); // 20.71 is the calculation product
$p->rotate(360 - 45);
$p->rect(0, 0, 100, 100);
$p->stroke();
$p->restore();

Result:

square rotation

That was simple enough.

However, I need to be able to rotate rectangle by arbitrary degree around its center. Things get complicated quickly with geometry :-)

Question: Does PDFlib support rotation of any object by arbitrary degree around its center?


Solution

  • Well, PDFlib won't do geometry for you. Here's the code to calculate offsets for the rotated rectangle:

    $x = 10;
    $y = 10;
    $width = 80;
    $height = 40;
    $angle = -33;
    $centerX = $width / 2;
    $centerY = $height / 2;
    // Diagonal angle
    $diagRadians = atan($width / $height);
    $diagAngle = rad2deg($diagRadians);
    // Half Length diagonal
    $diagHalfLength = sqrt(pow($height, 2) + pow($width, 2)) / 2;
    
    // Center coordinates of rotated rectangle.
    $rotatedCenterX = sin($diagRadians + deg2rad($angle)) * $diagHalfLength;
    $rotatedCenterY = cos($diagRadians + deg2rad($angle)) * $diagHalfLength;
    
    $offsetX = $centerX - $rotatedCenterX;
    $offsetY = $centerY - $rotatedCenterY;
    
    $p->setcolor('stroke', '#ff00ff', null, null, null, null);
    $p->save();
    $x += $offsetX;
    $y -= $offsetY;
    $p->translate($x, $y);
    // Place a dot at rotated rectangle center
    $p->circle($rotatedCenterX, $rotatedCenterY * -1, 5); 
    $p->stroke();
    $p->rotate(360 - $angle);
    $p->rect(0, 0, $width, $height);
    $p->stroke();
    $p->restore();