I'm generating an image with text in C++ using library called ImageMagick, and the DrawableRotation function does a rotation around the point of coordinates (0;0). (because it's an image it's top left corner )
The issue here is that I need to rotate my text label by a certain degree to put it on top of rectagle that has the same angle. ( text in box ) But the boxes are drown using the 4 points coordinates, I have their relative angle, which meens it's always positive, but some boxes are vertical, others are horizontal, and others are angled in between. here's an exemple: exemple of 3 boxes with different angles and their text
I would like to know if Image magick has an other way to rotate the text around itself or if there is a mathematical way to rotate the text so it has the good angle and then calculate the values I need to had to the coordinates to put it back at it's original coordinates.
I tried manually adding values to compensate the change in x;y but as all boxes have different angles, it's not dynamic enough, some labels get lost randomly on the image.
Well, I couldn't find a way to overcome this using the ImageMagick library directly, so what I do is make the rotation transformation around the origin before using the rotation formula from ImageMagick but in the opposite direction. But I also needed to map the angle (in degrees) from 90 to -90 so the text is always in the best direction to read. I'll post sample code for the rotation down below :
std::pair<float, float> MyImage::coorRotation(float x, float y, float angle)
{
float x_ = x*cos(angle) - y*sin(angle);
float y_ = x*sin(angle) + y*cos(angle);
return (std::make_pair(x_, y_));
}
for the rotation compensation and :
void MyImage::drawTextOnShapes()
float degrees = std::abs((atan2(this.shape.delta y, this.shape.delta x) * 180.0) / PI); // delta y = y2 - y1 and delta x = x2 - x1
if (degrees > 90)
degrees -= 180; // to map between 90 and -90
float radian = (degrees * PI) / 180;
float x = this.shape.center.x;
float y = this.shape.center.y;
std::pair coords = std::make_pair(x, y);
this->img.strokeColor("white");
coords = this->coorRotation(x, y, radian);
drawlist.push_back(DrawableRotation(-degrees));
stream << std::fixed << std::setprecision(2) << wall.length; // to get a .10 precision on the float output
drawlist.push_back(DrawableText(coords.first - textLenInPixels/2, coords.second, stream.str().append("m"))); // m for meters
this->img.draw(drawlist);
drawlist.clear();
this->saveImage();
}
And here's the result: