# Thread: How to get the coordinates of the 4 corners of a coaxial rectangle on the circle

1. ## How to get the coordinates of the 4 corners of a coaxial rectangle on the circle

Assuming that the short side of the rectangle A=10CM, the long side B=20CM, the diameter of the circle is the diagonal of the rectangle (hypotenuse)
At 0 degrees, the coordinates of the four corners of the rectangle relative to the center of the circle are X1, Y1 (X2, Y2), (X3, Y3), (X4, Y4)
When rotating at any angle, what are the coordinates of the four corners relative to the center coordinate system?

Trigonometric functions and arcs are all forgotten, and I dont know how to write this formula.
The main purpose is to obtain the required canvas size when a rectangular picture is rotated at any angle.   Reply With Quote

2. ## Re: How to get the coordinates of the 4 corners of a coaxial rectangle on the circle

0)
Code:
```X1= B/2 = 10, Y1 = A/2 = 5
X2= X1 = 10, Y2 = - Y1 = - 5```
1) Apply 2D rotation on the "relative to center"-coordinates of 2 points of the Rectangle (Not in the diagonal)
https://matthew-brett.github.io/teac...tation_2d.html
https://danceswithcode.net/engineeri...ons_in_2d.html

2) make these Rotated X Y coordinates Absolute values (Abs)
Code:
`RotX2 = Abs (RotX2)`
3) Find Max(x) and Max(y)
Code:
```if RotX2 > RotX1 then
maxRX = RotX2
else
maxRX = RotX1
End if```
4) new rectangle will be -maxRX to maxRX, -maxRY to maxRY

PS:
Not tested
Just tought on the fly

Edit:
other sources
https://gamedev.stackexchange.com/qu...d-rectangle-2d
https://math.stackexchange.com/quest...a-bounding-box  Reply With Quote

3. ## Re: How to get the coordinates of the 4 corners of a coaxial rectangle on the circle

Thanks a lot. However, my technical level is limited, too advanced, did not understand.

Yours is correct.

In fact, I want to calculate it like this. Rectangle picture is rotated arbitrarily. If you want to draw it to a control.This control needs how many big squares, mainly wants to solve this problem.

I now have a more complex matrix algorithm for rotating pictures. It requires an image frame as a carrier. But often four weeks will have a superfluous blank.

Because I created that square of diagonal length.Manual rotation of the image in the middle of the image will not run out, but there will be excess white edge.

Maybe there's another way. You can rotate the picture in pure code and save it.  Reply With Quote

4. ## Re: How to get the coordinates of the 4 corners of a coaxial rectangle on the circle

If you're using GDIplus to do the image rotation, you should be able to use the Matrix involved to convert an array of points, i.e. you pass it an array of the four corners and it will return an array of the points rotated.

The caveat is that I haven't done this with GDIplus. I've done it in .Net whose graphics are based on GDI+.
If it can be done in a .Net language, it should be doable using GDIplus with VB6.  Reply With Quote

5. ## Re: How to get the coordinates of the 4 corners of a coaxial rectangle on the circle

An example is here:
Rotating the rectangle will inevitably leave unpainted parts of the canvas.  Reply With Quote

6. ## Re: How to get the coordinates of the 4 corners of a coaxial rectangle on the circle Originally Posted by Argus19 An example is here:
Rotating the rectangle will inevitably leave unpainted parts of the canvas.
As long as you calculate the coordinates of the four points of the rotated rectangle, you can make the most perfect canvas, and then paint it without any extra white edge.  Reply With Quote

7. ## Re: How to get the coordinates of the 4 corners of a coaxial rectangle on the circle

I went ahead and looked up the gdip method GdipTransformPoints and played around with it a bit.
Since "The trick" already provided an example at the link in post #5, I used it as the playground.

Code:
```Private Enum CoordinateSpace
CoordinateSpaceworld     ' 0
CoordinateSpacepage      ' 1
CoordinateSpacedevice     ' 2
End Enum
Private Type POINTF
X As Single
Y As Single
End Type

Private Declare Function GdipTransformPoints Lib "gdiplus" (ByVal graphics As Long, ByVal destSpace As CoordinateSpace, ByVal srcSpace As CoordinateSpace, Points As POINTF, ByVal count As Long) As Long```
And I added code to the Draw sub to fill the array (which could have been done in Form_load since the values wouldn't change if the size of the picture doesn't change), a call to the transformPoints method, and a debug.print to print out the values, and added code to plot the points.

Since the values are relative to 0,0, the points plotted will always be around the center point of rotation.

If you move the picture to center on that center of rotation, then the four plotted points should rotate along with the corners of the picture, showing that the transformPoints method is transforming those four fixed corners to the points the current matrix that is part of the graphics object is using to draw with at that time.
Code:
```    Dim tstPoints(0 To 3) As POINTF
tstPoints(0).X = -iWidth / 2
tstPoints(0).Y = -iHeight / 2
tstPoints(1).X = iWidth / 2
tstPoints(1).Y = -iHeight / 2
tstPoints(2).X = iWidth / 2
tstPoints(2).Y = iHeight / 2
tstPoints(3).X = -iWidth / 2
tstPoints(3).Y = iHeight / 2
GdipTransformPoints graphics, CoordinateSpacedevice, CoordinateSpaceworld, tstPoints(0), 4
Debug.Print tstPoints(0).X; , ; tstPoints(0).Y,
Debug.Print tstPoints(1).X; , ; tstPoints(1).Y,
Debug.Print tstPoints(2).X; , ; tstPoints(2).Y,
Debug.Print tstPoints(3).X; , ; tstPoints(3).Y
'...
GdipDrawEllipse graphics, Pen, tstPoints(0).X, tstPoints(0).Y, 5, 5
GdipDrawEllipse graphics, Pen, tstPoints(1).X, tstPoints(1).Y, 5, 5
GdipDrawEllipse graphics, Pen, tstPoints(2).X, tstPoints(2).Y, 5, 5
GdipDrawEllipse graphics, Pen, tstPoints(3).X, tstPoints(3).Y, 5, 5```
"The trick"'s complete example code source with modifications...
Code:
```Private Type GdiplusStartupInput
GdiplusVersion              As Long
DebugEventCallback          As Long
SuppressExternalCodecs      As Long
End Type

Private Enum CoordinateSpace
CoordinateSpaceworld     ' 0
CoordinateSpacepage      ' 1
CoordinateSpacedevice     ' 2
End Enum
Private Type POINTF
X As Single
Y As Single
End Type

Private Const UnitPixel                     As Long = 2
Private Const InterpolationModeHighQuality  As Long = 2

Private Declare Function GdipDrawImageRect Lib "gdiplus" (ByVal graphics As Long, ByVal image As Long, ByVal X As Single, ByVal Y As Single, ByVal Width As Single, ByVal Height As Single) As Long
Private Declare Function GdipGetImageWidth Lib "gdiplus" (ByVal image As Long, Width As Long) As Long
Private Declare Function GdipGetImageHeight Lib "gdiplus" (ByVal image As Long, Height As Long) As Long
Private Declare Function GdipDisposeImage Lib "gdiplus" (ByVal image As Long) As Long
Private Declare Function GdiplusStartup Lib "gdiplus" (token As Long, inputbuf As GdiplusStartupInput, Optional ByVal outputbuf As Long = 0) As Long
Private Declare Function GdipCreateFromHDC Lib "gdiplus" (ByVal hdc As Long, graphics As Long) As Long
Private Declare Function GdipDeleteGraphics Lib "gdiplus" (ByVal graphics As Long) As Long
Private Declare Function GdiplusShutdown Lib "gdiplus" (ByVal token As Long) As Long
Private Declare Function GdipTranslateWorldTransform Lib "gdiplus" (ByVal graphics As Long, ByVal dx As Single, ByVal dy As Single, ByVal order As Long) As Long
Private Declare Function GdipRotateWorldTransform Lib "gdiplus" (ByVal graphics As Long, ByVal angle As Single, ByVal order As Long) As Long
Private Declare Function GdipCreatePen1 Lib "gdiplus" (ByVal color As Long, ByVal Width As Single, ByVal unit As Long, Pen As Long) As Long
Private Declare Function GdipDeletePen Lib "gdiplus" (ByVal Pen As Long) As Long
Private Declare Function GdipCreateBitmapFromHBITMAP Lib "gdiplus" (ByVal hbm As Long, ByVal hpal As Long, Bitmap As Long) As Long
Private Declare Function GdipGraphicsClear Lib "gdiplus" (ByVal graphics As Long, ByVal lColor As Long) As Long
Private Declare Function GdipDrawEllipse Lib "gdiplus" (ByVal graphics As Long, ByVal Pen As Long, ByVal X As Single, ByVal Y As Single, ByVal Width As Single, ByVal Height As Single) As Long
Private Declare Function GdipResetWorldTransform Lib "gdiplus" (ByVal graphics As Long) As Long

Private Declare Function GdipTransformPoints Lib "gdiplus" (ByVal graphics As Long, ByVal destSpace As CoordinateSpace, ByVal srcSpace As CoordinateSpace, Points As POINTF, ByVal count As Long) As Long

Dim SrcPicture  As StdPicture
Dim Bitmap      As Long
Dim graphics    As Long
Dim GpInput     As GdiplusStartupInput
Dim token       As Long
Dim Pen         As Long

picOut.AutoRedraw = True

Set SrcPicture = picSrc.Picture

hsclXPos.Max = picSrc.ScaleWidth
vsclYPos.Max = picSrc.ScaleHeight

GpInput.GdiplusVersion = 1
GdiplusStartup token, GpInput

GdipCreateFromHDC picOut.hdc, graphics

GdipCreateBitmapFromHBITMAP SrcPicture.Handle, SrcPicture.hpal, Bitmap
GdipCreatePen1 vbCyan Or &HFF000000, 4, UnitPixel, Pen
DrawCenter
Draw

End Sub

Private Sub DrawCenter()
picSrc.PaintPicture SrcPicture, 0, 0
picSrc.PSet (hsclXPos.Value, vsclYPos.Value)
picSrc.Refresh
End Sub

Private Sub Draw()
Dim iWidth As Long, iHeight As Long

GdipRotateWorldTransform graphics, hsclAnle.Value, 1
GdipTranslateWorldTransform graphics, picOut.ScaleWidth / 2, picOut.ScaleHeight / 2, 1
GdipGraphicsClear graphics, &HFFFFFFFF
GdipGetImageWidth Bitmap, iWidth
GdipGetImageHeight Bitmap, iHeight
GdipDrawImageRect graphics, Bitmap, -hsclXPos.Value, -vsclYPos.Value, iWidth, iHeight
Dim tstPoints(0 To 3) As POINTF
tstPoints(0).X = -iWidth / 2
tstPoints(0).Y = -iHeight / 2
tstPoints(1).X = iWidth / 2
tstPoints(1).Y = -iHeight / 2
tstPoints(2).X = iWidth / 2
tstPoints(2).Y = iHeight / 2
tstPoints(3).X = -iWidth / 2
tstPoints(3).Y = iHeight / 2
GdipTransformPoints graphics, CoordinateSpacedevice, CoordinateSpaceworld, tstPoints(0), 4
Debug.Print tstPoints(0).X; , ; tstPoints(0).Y,
Debug.Print tstPoints(1).X; , ; tstPoints(1).Y,
Debug.Print tstPoints(2).X; , ; tstPoints(2).Y,
Debug.Print tstPoints(3).X; , ; tstPoints(3).Y

GdipResetWorldTransform graphics
GdipDrawEllipse graphics, Pen, picOut.ScaleWidth / 2, picOut.ScaleHeight / 2, 3, 3

GdipDrawEllipse graphics, Pen, tstPoints(0).X, tstPoints(0).Y, 5, 5
GdipDrawEllipse graphics, Pen, tstPoints(1).X, tstPoints(1).Y, 5, 5
GdipDrawEllipse graphics, Pen, tstPoints(2).X, tstPoints(2).Y, 5, 5
GdipDrawEllipse graphics, Pen, tstPoints(3).X, tstPoints(3).Y, 5, 5

picOut.Refresh
End Sub

GdipDeleteGraphics graphics
GdipDeletePen Pen
GdipDisposeImage (Bitmap)
GdiplusShutdown (token)
End Sub

Private Sub hsclAnle_Change()
Draw
DrawCenter
End Sub

Private Sub hsclAnle_Scroll()
hsclAnle_Change
End Sub

Private Sub hsclXPos_Change()
Draw
DrawCenter
End Sub

Private Sub hsclXPos_Scroll()
hsclXPos_Change
End Sub

Private Sub vsclYPos_Change()
Draw
DrawCenter
End Sub

Private Sub vsclYPos_Scroll()
vsclYPos_Change
End Sub```  Reply With Quote

8. ## Re: How to get the coordinates of the 4 corners of a coaxial rectangle on the circle

How to use GDIPLUS to rotate a picture 90 degrees, 180 degrees, 270 degrees, this kind of code is very rare.
How to rotate at any angle, this kind of code has not been found after searching hundreds of pages on the Internet.
Input file 1.PNG, set to rotate 35 degrees, save as 2.png  Reply With Quote

9. ## Re: How to get the coordinates of the 4 corners of a coaxial rectangle on the circle

The Tricks code rotates at any angle you choose. If you want to rotate 90, 180 or 270, just choose those angles.

If you wanted the code in VB.Net, I might whip it out, but I probably won't.
If you want it in VB6, I would have to research, and I'm pretty sure I won't.
I know there should be plenty of examples of reading in png and writing png files from VB6, and you can modify "The trick" code to do the rotation you want, and the modification I did to figure out the size of the bitmap needed.

You could also have figured the bitmap sizing based on what reexre posted as well since it should give you essentially the same answer for the four corners.

So, find the pieces and put it together.
1. Load 1.PNG into a bitmap.

2. Either use reexre's code to calculate the four corners at 35 degrees to determine the size of the bitmap you need or you could create the transforms with Gdip in a graphics object and determine the four corners from that. You don't actually have to draw before you use the graphics object's transformation matrix to figure out the four corners.

3. Create a bitmap the size needed based on step 2.

4. Get a graphics object for the bitmap created in step 3, apply the transforms to that graphics object and draw the original bitmap into that bitmap.

5. Save that bitmap to 2.png  Reply With Quote

10. ## Re: How to get the coordinates of the 4 corners of a coaxial rectangle on the circle Originally Posted by passel If you want it in VB6, I would have to research, ...
...what the OP wants is probably this (RC5/RC6-based):
Code:
```Public Function GetRotatedSurface(SrcSrf As cCairoSurface, ByVal AngDeg As Double) As cCairoSurface
Dim CC As cCairoContext, x1#, y1#, x2#, y2#, SrcPat As cCairoPattern

'first, a "measure"-context is used to retrieve the Bounding-Rect
Set CC = SrcSrf.CreateContext
CC.Rectangle 0, 0, SrcSrf.Width, SrcSrf.Height
CC.RotateDrawingsDeg -AngDeg
CC.GetPathExtents x1, y1, x2, y2 '<- retrieve TopLeft- and BottomRight-points of the Bounding-Rect

'now use the right size to create the ResultSurface-Context, to render the rotated SrcSrf (wrapped in a Pattern)
Set CC = Cairo.CreateSurface(Abs(x1 - x2), Abs(y1 - y2)).CreateContext
Set SrcPat = SrcSrf.CreateSurfacePattern() 'a thin wrapper, to be able to apply the transforms in the next line
Set SrcPat.Matrix = SrcPat.Matrix.RotateCoordsDeg(-AngDeg).TranslateCoords(x1, y1)
CC.Paint 1, SrcPat 'render the (Src)pattern to the properly resized result-surface-context

Set GetRotatedSurface = CC.Surface 'return the result
End Function```
The above routine expects a Source-Surface -
and returns the result as another (usually larger, after rotation) ImageSurface-Object.
And since any cCairoSurface can be written to Png or JPG (just using a method-call on the Result-Surface),
the whole task could be wrapped-up without larger issues.

Olaf  Reply With Quote

11. ## Re: How to get the coordinates of the 4 corners of a coaxial rectangle on the circle

Maybe look at GdipImageRotateFlip()? Should be faster than the fine rotation calls.  Reply With Quote

12. ## Re: How to get the coordinates of the 4 corners of a coaxial rectangle on the circle

Code:
```Private Type POINTAPI
X As Long
Y As Long
End Type

Private Function RotatePoints(nSource() As POINTAPI, ByVal nAngleDegrees As Single) As POINTAPI()
Dim iCenter As POINTAPI
Dim iLeft As Long
Dim iTop As Long
Dim iRight As Long
Dim iBottom As Long
Dim c As Long
Dim iUb As Long
Dim iCos As Single
Dim iSin As Single
Dim iRet() As POINTAPI

If nAngleDegrees > 360 Then nAngleDegrees = nAngleDegrees Mod 360
If nAngleDegrees < 0 Then nAngleDegrees = 360 + nAngleDegrees Mod -360

iAngleInRadians = nAngleDegrees * 3.14159265359 / 180

iUb = UBound(nSource)
ReDim iRet(iUb)

iLeft = nSource(0).X
iRight = nSource(0).X
iTop = nSource(0).Y
iBottom = nSource(0).Y

For c = 1 To iUb
If nSource(c).X < iLeft Then iLeft = nSource(c).X
If nSource(c).X > iRight Then iRight = nSource(c).X
If nSource(c).Y < iTop Then iTop = nSource(c).Y
If nSource(c).Y > iBottom Then iBottom = nSource(c).Y
Next

iCenter.X = (iLeft + iRight) / 2
iCenter.Y = (iTop + iBottom) / 2

For c = 0 To iUb
iRet(c).X = (nSource(c).X - iCenter.X) * iCos - (nSource(c).Y - iCenter.Y) * iSin + iCenter.X
iRet(c).Y = (nSource(c).X - iCenter.X) * iSin + (nSource(c).Y - iCenter.Y) * iCos + iCenter.Y
Next
RotatePoints = iRet
End Function```  Reply With Quote

13. ## Re: How to get the coordinates of the 4 corners of a coaxial rectangle on the circle Originally Posted by Eduardo- Private Function RotatePoints(nSource() As POINTAPI, ByVal nAngleDegrees As Single) As POINTAPI()
The OPs question was (IMO) not about the rotation itself, but about "finding the bounding-box":
https://stackoverflow.com/questions/...lement-via-jav

reexre tried to cover that as well in his reply (and links) in #2.

Olaf  Reply With Quote

14. ## Re: How to get the coordinates of the 4 corners of a coaxial rectangle on the circle Originally Posted by Schmidt The OPs question was (IMO) not about the rotation itself, but about "finding the bounding-box":
https://stackoverflow.com/questions/...lement-via-jav

reexre tried to cover that as well in his reply (and links) in #2.

Olaf
OK, this can be achieved with another auxiliary function:

Code:
```Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Private Function FindBoundingBoxPointsRotated(nPoints() As POINTAPI, ByVal nAngleDegrees As Single) As RECT
Dim iRotated() As POINTAPI
Dim c As Long

iRotated = RotatePoints(nPoints, nAngleDegrees)
FindBoundingBoxPointsRotated.Left = iRotated(0).X
FindBoundingBoxPointsRotated.Right = iRotated(0).X
FindBoundingBoxPointsRotated.Top = iRotated(0).Y
FindBoundingBoxPointsRotated.Bottom = iRotated(0).Y
For c = 1 To UBound(iRotated)
If iRotated(c).X < FindBoundingBoxPointsRotated.Left Then FindBoundingBoxPointsRotated.Left = iRotated(c).X
If iRotated(c).X > FindBoundingBoxPointsRotated.Right Then FindBoundingBoxPointsRotated.Right = iRotated(c).X
If iRotated(c).Y < FindBoundingBoxPointsRotated.Top Then FindBoundingBoxPointsRotated.Top = iRotated(c).Y
If iRotated(c).Y > FindBoundingBoxPointsRotated.Bottom Then FindBoundingBoxPointsRotated.Bottom = iRotated(c).Y
Next
End Function```  Reply With Quote

15. ## Re: How to get the coordinates of the 4 corners of a coaxial rectangle on the circle

For rotations, paths, textures, brushes, etc. Maybe it's like rc6.dll. It takes 100 pages of help to learn most of the tricks.(for gdiplus.dll)  Reply With Quote

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•