RotatePicture – Rotate a 256-color bitmap by any angle (super-optimized version)

RotatePicture – Rotate a 256-color bitmap by any angle (super-optimized version)

' This structure holds Bitmap informationPrivate Type BITMAP    bmType As Long    bmWidth As Long    bmHeight As Long    bmWidthBytes As Long    bmPlanes As Integer    bmBitsPixel As Integer    bmBits As LongEnd Type' This structure holds SAFEARRAY infoPrivate Type SafeArray2    cDims As Integer    fFeatures As Integer    cbElements As Long    cLocks As Long    pvData As Long    cElements1 As Long    lLbound1 As Long    cElements2 As Long    lLbound2 As LongEnd Type' API declaresPrivate Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As _    Any, pSrc As Any, ByVal ByteLen As Long)Private Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectA" (ByVal _    hObject As Long, ByVal nCount As Long, lpObject As Any) As Long' Rotate a 256-color bitmap by any angle:'   sourcePB is the source PictureBox control (may be hidden)'   destPB is the destination PictureBox control'   XC, YC are the coordinates of the rotation center'   ANGLE is the rotation angle in degrees' this improved version scans only a portion of the image, and builds' remaining points using simmetry. This algorithm is particularly efficient ' when the' center of the rotation is inside the bitmap, the best performances are ' achieved' when it is near to the center of the bitmap. Moreover, this code saves some' CPU time by using pre-calculated values for SIN, COS, and SQR functions.' IMPORTANT: the source and destination PictureBox control must initially' contain the *same* bitmap, to ensure that size and color palette' are correctly initialized.' Example:'    'Load the same image in both source (hidden) and destination controls'    Picture1.Picture = LoadPicture("d:winntgone fishing.bmp")'    Picture2.Picture = LoadPicture("d:winntgone fishing.bmp")'    ' Rotate by 360°'    Dim a As Single'    For a = 0 To 360 Step 5'        RotatePicture2 Picture1, Picture2, 50, 50, a'    NextPrivate Sub RotatePicture2(sourcePB As PictureBox, destPB As PictureBox, _    xc As Long, yc As Long, degrees As Single)    ' all angles are expressed in 1/10000ths of radians    Const PI As Long = 31416    Const HALFPI As Long = 15707    Const DOUBLEPI As Long = 62831        Const SQRTABLE_MAX As Long = 40000        Static sinTable() As Single    Static atnTable() As Long    Static sqrTable() As Single    Static initialized As Boolean        ' these are used to address the pixel using matrices    Dim pict1() As Byte    Dim pict2() As Byte    Dim p1 As SafeArray2, p2 As SafeArray2    Dim bmp1 As BITMAP, bmp2 As BITMAP    ' these are used by the rotating algorithm    Dim radians As Long    Dim angle As Long    Dim angle0 As Long    Dim distance As Single    Dim distanceSquared As Long    Dim deltaX As Long, deltaY As Long    Dim deltaXSquared As Single, deltaX10000 As Long    Dim x As Long, y As Long    Dim dx As Long, dy As Long    Dim x0 As Long, y0 As Long    Dim xx As Long, yy As Long    Dim xStart As Long, xEnd As Long    Dim yStart As Long, yEnd As Long    Dim bmWidth1 As Long    Dim bmHeight1 As Long        ' Initialize sin,cos,sqr tables    If Not initialized Then        initialized = True                Dim i As Long        ' evaluate a table of sin for 360+90 degrees        ' with a precision of 1/10000 of a radian        ' this permits to reuse the same table for cosine, too        ' since COX(x) = SIN(x + 90°)        ReDim sinTable(0 To 62831 + 15709) As Single        For i = 0 To UBound(sinTable)            sinTable(i) = Sin(i / 10000)        Next                ' evaluate a table for Atn(x)*10000 for x=[0,1], with steps of 0,0001        ReDim atnTable(0 To 10000) As Long        For i = LBound(atnTable) To UBound(atnTable)            atnTable(i) = Atn(i / 10000) * 10000#        Next                ' evaluate a table for Sqr(i)        ReDim sqrTable(SQRTABLE_MAX) As Single        For i = 0 To SQRTABLE_MAX            sqrTable(i) = Sqr(i)        Next    End If        ' get bitmap info    GetObjectAPI sourcePB.Picture, Len(bmp1), bmp1    GetObjectAPI destPB.Picture, Len(bmp2), bmp2    If bmp1.bmPlanes <> 1 Or bmp1.bmBitsPixel <> 8 Or bmp2.bmPlanes <> 1 Or _        bmp2.bmBitsPixel <> 8 Then        MsgBox "This routine supports 256-color bitmaps only", vbCritical        Exit Sub    End If        ' have the local matrices point to bitmap pixels    With p1        .cbElements = 1        .cDims = 2        .lLbound1 = 0        .cElements1 = bmp1.bmHeight        .lLbound2 = 0        .cElements2 = bmp1.bmWidthBytes        .pvData = bmp1.bmBits    End With    CopyMemory ByVal VarPtrArray(pict1), VarPtr(p1), 4        With p2        .cbElements = 1        .cDims = 2        .lLbound1 = 0        .cElements1 = bmp2.bmHeight        .lLbound2 = 0        .cElements2 = bmp2.bmWidthBytes        .pvData = bmp2.bmBits    End With    CopyMemory ByVal VarPtrArray(pict2), VarPtr(p2), 4        ' convert the angle into 1/10000ths of radians    ' subtracting 628310000 ensure that when radians is used in the    ' subtraction in the loop, it produces a positive number    radians = degrees / (180 / 3.14159) * 10000& - 628310000        ' we have several cases, depending on where XC falls    ' compared to the center of the image    If xc < bmp2.bmWidth  2 Then        xStart = xc        xEnd = bmp2.bmWidth - 1    Else        xStart = 0        xEnd = xc    End If    If yc < bmp2.bmHeight  2 Then        yStart = yc        yEnd = bmp2.bmWidth - 1    Else        yStart = 0        yEnd = yc    End If        ' the main loop of this routine scans a squared portion    ' of the image whose corners falls on the rotation center    ' Of the four squares that touch the rotation center, here    ' we choose the one with the highest number of pixels    ' withing the image        If xEnd - xStart > yEnd - yStart Then        If yStart = 0 Then            yStart = yEnd - (xEnd - xStart)        Else            yEnd = yStart + (xEnd - xStart)        End If    Else        If xStart = 0 Then            xStart = xEnd - (yEnd - yStart)        Else            xEnd = xStart + (yEnd - yStart)        End If    End If    bmWidth1 = bmp1.bmWidth    bmHeight1 = bmp1.bmHeight        ' rotate the picture        For x = xStart To xEnd        ' these values are loop invariant for the following For-Next        deltaX = x - xc        deltaXSquared = deltaX * deltaX        deltaX10000 = deltaX * 10000        For y = yStart To yEnd            deltaY = y - yc                        ' evaluate the arc-tangent of (deltaY/deltaX)            ' many IFs are required, since the atnTable() array only            ' covers the range [0,1] - if (deltaY/deltaX) is > 1 we            ' must use its reciprocal deltaX/deltaY            If deltaX > 0 Then                If deltaY >= 0 Then                    If deltaY < deltaX Then                        angle = atnTable((deltaY * 10000)  deltaX)                    Else                        angle = HALFPI - atnTable(deltaX10000  deltaY)                    End If                Else                    If -deltaY < deltaX Then                        angle = -atnTable((deltaY * -10000)  deltaX)                    Else                        angle = -HALFPI + atnTable(-deltaX10000  deltaY)                    End If                End If            ElseIf deltaX < 0 Then                If deltaY > 0 Then                    If deltaY < -deltaX Then                        angle = PI - atnTable((deltaY * -10000)  deltaX)                    Else                        angle = HALFPI + atnTable(-deltaX10000  deltaY)                    End If                Else                    If deltaY > deltaX Then                        angle = PI + atnTable((deltaY * 10000)  deltaX)                    Else                        angle = -HALFPI - atnTable(deltaX10000  deltaY)                    End If                End If            Else                If deltaY >= 0 Then                    angle = HALFPI                Else                    angle = -HALFPI                End If            End If            ' --- end of arc-tangent evaluation                            ' "angle" is the angle of the segment that goes from            ' the center to (x,y) - since we wish to evaluate the            ' color of this point, we must check the point in the            ' original bitmap that has the same distance from the            ' center but with a different angle                            ' evaluate the distance of (x,y) from the rotation            ' center, using if possible the value already stored            ' in sqrTable()            distanceSquared = deltaXSquared + deltaY * deltaY            If distanceSquared <= SQRTABLE_MAX Then                distance = sqrTable(distanceSquared)            Else                distance = Sqr(distanceSquared)            End If                        ' the old point in the original bitmap has same            ' distance but a different angle            angle0 = (angle - radians) Mod DOUBLEPI                        ' evaluate the x,y offset of the old point from            ' the rotation center            dx = distance * sinTable(angle0 + HALFPI)  ' really cosine            dy = distance * sinTable(angle0)                        ' if (x,y) falls within the image            If x >= 0 And x < bmWidth1 And y >= 0 And y < bmHeight1 Then                ' (x0,y0) is the corresponding point in the original bitmap                x0 = xc + dx                y0 = yc + dy                ' if (x0,y0) falls within the bitmap boundaries, copy the pixel                ' else, set the (x,y) pixel to zero (background color)                If x0 >= 0 And x0 < bmWidth1 And y0 >= 0 And y0 < bmHeight1 Then                    pict2(x, y) = pict1(x0, y0)                Else                    pict2(x, y) = 0                End If                            ' this is the point simmetrical to the rotation center - this                ' block is within the outer If clause because the simmetrical                ' point can be within the bitmap only if (x,y) was within the                ' bitmap too                xx = xc - deltaX                yy = yc - deltaY                If xx >= 0 And xx < bmWidth1 And yy >= 0 And yy < bmHeight1 Then                    x0 = xc - dx                    y0 = yc - dy                    If x0 >= 0 And x0 < bmWidth1 And y0 >= 0 And y0 < bmHeight1 _                        Then                        pict2(xx, yy) = pict1(x0, y0)                    Else                        pict2(xx, yy) = 0                    End If                End If                        End If                        ' now deal with the pixel 90° ahead of the one in (x,y)            xx = xc + deltaY            yy = yc - deltaX            If xx >= 0 And xx < bmWidth1 And yy >= 0 And yy < bmHeight1 Then                x0 = xc + dy                y0 = yc - dx                If x0 >= 0 And x0 < bmWidth1 And y0 >= 0 And y0 < bmHeight1 Then                    pict2(xx, yy) = pict1(x0, y0)                Else                    pict2(xx, yy) = 0                End If            End If            ' now deal with the pixel 270° ahead of the one in (x,y)            xx = xc - deltaY            yy = yc + deltaX            If xx >= 0 And xx < bmWidth1 And yy >= 0 And yy < bmHeight1 Then                x0 = xc - dy                y0 = yc + dx                If x0 >= 0 And x0 < bmWidth1 And y0 >= 0 And y0 < bmHeight1 Then                    pict2(xx, yy) = pict1(x0, y0)                Else                    pict2(xx, yy) = 0                End If            End If        Next    Next        ' release arrays    CopyMemory ByVal VarPtrArray(pict1), 0&, 4    CopyMemory ByVal VarPtrArray(pict2), 0&, 4        ' show the rotated bitmap    destPB.Refresh    End Sub' Support routinePrivate Function VarPtrArray(arr As Variant) As Long    CopyMemory VarPtrArray, ByVal VarPtr(arr) + 8, 4End Function

devx-admin

devx-admin

Share the Post:
AI Software Development

ChatGPT is Now Making Video Games

Pietro Schirano’s foray into using ChatGPT, an AI tool for programming, has opened up new vistas in game and software development. As design lead at

Llama Codebot

Developers! Here’s Your Chatbot

Meta Platforms has recently unveiled Code Llama, a free chatbot designed to aid developers in crafting coding scripts. This large language model (LLM), developed using

Tech Layoffs

Unraveling the Tech Sector’s Historic Job Losses

Throughout 2023, the tech sector has experienced a record-breaking number of job losses, impacting tens of thousands of workers across various companies, including well-established corporations

Chinese 5G Limitation

Germany Considers Limiting Chinese 5G Tech

A recent report has put forth the possibility that Germany’s Federal Ministry of the Interior and Community may consider limiting the use of Chinese 5G

Modern Warfare

The Barak Tank is Transforming Modern Warfare

The Barak tank is a groundbreaking addition to the Israeli Defense Forces’ arsenal, significantly enhancing their combat capabilities. This AI-powered military vehicle is expected to

AI Software Development

ChatGPT is Now Making Video Games

Pietro Schirano’s foray into using ChatGPT, an AI tool for programming, has opened up new vistas in game and software development. As design lead at business finance firm Brex, Schirano

Llama Codebot

Developers! Here’s Your Chatbot

Meta Platforms has recently unveiled Code Llama, a free chatbot designed to aid developers in crafting coding scripts. This large language model (LLM), developed using Meta’s Llama 2 model, serves

Tech Layoffs

Unraveling the Tech Sector’s Historic Job Losses

Throughout 2023, the tech sector has experienced a record-breaking number of job losses, impacting tens of thousands of workers across various companies, including well-established corporations and emerging startups in areas

Chinese 5G Limitation

Germany Considers Limiting Chinese 5G Tech

A recent report has put forth the possibility that Germany’s Federal Ministry of the Interior and Community may consider limiting the use of Chinese 5G technology by local network providers

Modern Warfare

The Barak Tank is Transforming Modern Warfare

The Barak tank is a groundbreaking addition to the Israeli Defense Forces’ arsenal, significantly enhancing their combat capabilities. This AI-powered military vehicle is expected to transform the way modern warfare

AI Cheating Growth

AI Plagiarism Challenges Shake Academic Integrity

As generative AI technologies like ChatGPT become increasingly prevalent among students and raise concerns about widespread cheating, prominent universities have halted their use of AI detection software, such as Turnitin’s

US Commitment

US Approves Sustainable Battery Research

The US Department of Energy has revealed a $325 million commitment in the research of innovative battery types, designed to enable solar and wind power as continuous, 24-hour energy sources.

Netanyahu Musk AI

Netanyahu and Musk Discuss AI Future

On September 22, 2023, Israeli Prime Minister Benjamin Netanyahu met with entrepreneur Elon Musk in San Francisco prior to attending the United Nations. In a live-streamed discussion, Netanyahu lauded Musk

Urban Gardening

Creating Thriving Cities Through Urban Gardening

The rising popularity of urban gardening is receiving increased recognition for its numerous advantages, as demonstrated in a recent study featured in the Environmental Research Letters journal. Carried out by

What You Need to Know About Cloud Security Strategies

What You Need to Know About Cloud Security Strategies

Today, many businesses are adopting cloud computing services. As a result, it’s important to recognize that security measures for data in the cloud are different from those in traditional on-premises

Romanian Energy Security

Eastern Europe is Achieving Energy Security

Canada and Romania have solidified their commitment to energy security and independence from Russian energy exports by signing a $3-billion export development agreement. The deal is centered on constructing two

Seamless Integration

Unlocking Seamless Smart Home Integration

The vision of an intelligently organized and interconnected smart home that conserves time, energy, and resources has long been desired by many homeowners. However, this aspiration has often been hindered

New Algorithm

MicroAlgo’s Groundbreaking Algorithm

MicroAlgo Inc. has revealed the creation of a knowledge-augmented backtracking search algorithm, developed through extensive research in evolutionary computational techniques. The algorithm is designed to boost problem-solving effectiveness, precision, and

Poland Energy Future

Westinghouse Builds Polish Power Plant

Westinghouse Electric Company and Bechtel have come together to establish a formal partnership in order to design and construct Poland’s inaugural nuclear power plant at the Lubiatowo-Kopalino site in Pomerania.

EV Labor Market

EV Industry Hurting For Skilled Labor

The United Auto Workers strike has highlighted the anticipated change towards a future dominated by electric vehicles (EVs), a shift which numerous people think will result in job losses. However,

Soaring EV Quotas

Soaring EV Quotas Spark Battle Against Time

Automakers are still expected to meet stringent electric vehicle (EV) sales quotas, despite the delayed ban on new petrol and diesel cars. Starting January 2023, more than one-fifth of automobiles

Affordable Electric Revolution

Tesla Rivals Make Bold Moves

Tesla, a name synonymous with EVs, has consistently been at the forefront of the automotive industry’s electric revolution. The products that Elon Musk has developed are at the forefront because

Sunsets' Technique

Inside the Climate Battle: Make Sunsets’ Technique

On February 12, 2023, Luke Iseman and Andrew Song from the solar geoengineering firm Make Sunsets showcased their technique for injecting sulfur dioxide (SO₂) into the stratosphere as a means

AI Adherence Prediction

AI Algorithm Predicts Treatment Adherence

Swoop, a prominent consumer health data company, has unveiled a cutting-edge algorithm capable of predicting adherence to treatment in people with Multiple Sclerosis (MS) and other health conditions. Utilizing artificial

Personalized UX

Here’s Why You Need to Use JavaScript and Cookies

In today’s increasingly digital world, websites often rely on JavaScript and cookies to provide users with a more seamless and personalized browsing experience. These key components allow websites to display

Geoengineering Methods

Scientists Dimming the Sun: It’s a Good Thing

Scientists at the University of Bern have been exploring geoengineering methods that could potentially slow down the melting of the West Antarctic ice sheet by reducing sunlight exposure. Among these

why startups succeed

The Top Reasons Why Startups Succeed

Everyone hears the stories. Apple was started in a garage. Musk slept in a rented office space while he was creating PayPal with his brother. Facebook was coded by a