Rotation Artefacts

Just starting out? Need help? Post your questions and find answers here.
matalog
Enthusiast
Enthusiast
Posts: 165
Joined: Tue Sep 05, 2017 10:07 am

Rotation Artefacts

Post by matalog »

Is there a way to remove the 'holes' in the rotated parts of the image that this program creates?

This is not a flaw in Purebasic, it seems to be the rotation method that causes them to appear, only when a rotation of any number not a multiple of 90 degrees.

Code: Select all

If OpenWindow(0, 100, 200, 1000, 1000, "Rotation Artefacts")

  If CreateImage(0, 1000, 1000)
    If StartDrawing(ImageOutput(0))
       For x=100 To 200
         For y=100 To 200
           For j=1 To 6
            Plot (500+Cos (j*#PI/3)*x-Sin (j*#PI/3)*y,500+Sin (j*#PI/3)*x+Cos (j*#PI/3)*y,16777432) 
          Next  
        Next
      Next 

      StopDrawing()
    EndIf
  EndIf
  
  ImageGadget(0, 0, 0, 0, 0, ImageID(0))

  Repeat
    Event = WaitWindowEvent() 
  Until Event = #PB_Event_CloseWindow  
  
EndIf

End 
BarryG
Addict
Addict
Posts: 3294
Joined: Thu Apr 18, 2019 8:17 am

Re: Rotation Artefacts

Post by BarryG »

Might be easier (and faster) just to draw each box border, and then fill the insides of each box with FillArea().
infratec
Always Here
Always Here
Posts: 6818
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Rotation Artefacts

Post by infratec »

It comes from the rounding of the float results.

As already mentioned: use FillArea()
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4637
Joined: Sun Apr 12, 2009 6:27 am

Re: Rotation Artefacts

Post by RASHAD »

Another option
Use VectorDrawing lib.
Full of what you need
Example:

Code: Select all

If OpenWindow(0, 0, 0, 1000, 1000, "Rotation Artefacts",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  
  CreateImage(0, 1000, 1000)
  CreateImage(1,80,80,24,$0000FF)
  StartVectorDrawing(ImageVectorOutput(0))
  MovePathCursor(500,200)
  DrawVectorImage(ImageID(1),255)
  MovePathCursor(500,700)
  DrawVectorImage(ImageID(1),255)
  ;*******************************
  ResetPath()
  ResetCoordinates()
  RotateCoordinates(320,300,30)
  MovePathCursor(320,300)
  DrawVectorImage(ImageID(1),255)
  ResetPath()
  ResetCoordinates()
  RotateCoordinates(340,550,60)
  MovePathCursor(340,550)
  DrawVectorImage(ImageID(1),255)
  ;*******************************
  ResetPath()
  ResetCoordinates()
  RotateCoordinates(690,350,330)
  MovePathCursor(690,350)
  DrawVectorImage(ImageID(1),255)
  ResetPath()
  ResetCoordinates()
  RotateCoordinates(690,640,300)
  MovePathCursor(690,640)
  DrawVectorImage(ImageID(1),255)
  StopVectorDrawing()
  
  ImageGadget(0, 0, 0, 0, 0, ImageID(0))
  
  Repeat
    Event = WaitWindowEvent() 
  Until Event = #PB_Event_CloseWindow  
  
EndIf
End 
Edit : Use your own calculations
Egypt my love
matalog
Enthusiast
Enthusiast
Posts: 165
Joined: Tue Sep 05, 2017 10:07 am

Re: Rotation Artefacts

Post by matalog »

Thanks for the tips.

I was hoping for a general way around the aliasing problems this method of rotation suffers from.

The boxes were just an example to show that all points are definitely being drawn in the original description of the shape. In general when I would want to use this type of rotation, the things drawn would not be uniform shapes.
User avatar
IceSoft
Addict
Addict
Posts: 1616
Joined: Thu Jun 24, 2004 8:51 am
Location: Germany

Re: Rotation Artefacts

Post by IceSoft »

Use bigger Points 😏
Belive!
<Wrapper>4PB, PB<game>, =QONK=, PetriDish, Movie2Image, PictureManager,...
matalog
Enthusiast
Enthusiast
Posts: 165
Joined: Tue Sep 05, 2017 10:07 am

Re: Rotation Artefacts

Post by matalog »

I was able to work this out myself eventually, and here is the answer. It's based on the three-shear method of rotation.

It works about any centre, or its own centre.

Code: Select all

If OpenWindow(0, 100, 200, 1000, 1000, "No Rotation Artefacts")
  
  If CreateImage(0, 1000, 1000)
    If StartDrawing(ImageOutput(0))
      For x=100 To 200
        For y=100 To 200
          For j=0 To 360 Step 60
            Global.f angle=j * #PI/180
            Global.i nx, ny
            col = RGB(32*Mod(32+Int((x+y)/16), 13), 5, 50)
            rc.i = Int(angle/(#PI/2)) ; Determine the rotation count
            angle = angle - rc*#PI/2
            rc = Mod(rc, 4)
            
            g.d=Tan(angle/2)
            h.d=Sin(angle)
            
            Select rc
              Case 0
                nx = x : ny = y
              Case 1
                nx = -y : ny = x
              Case 2
                nx = -x : ny = -y
              Case 3
                nx = y : ny = -x
            EndSelect
            
            
            nx=nx-g*ny
            ny=(nx)*h+ny
            nx=nx-ny*g
            Plot (500+nx,500+ny,col) 
          Next  
        Next
      Next 
      
      StopDrawing()
    EndIf
  EndIf
  
  ImageGadget(0, 0, 0, 0, 0, ImageID(0))
  
  Repeat
    Event = WaitWindowEvent() 
  Until Event = #PB_Event_CloseWindow  
  
EndIf

End
Post Reply