diff --git a/examples/ExampleReplaceRectangles/ExampleReplaceRectangles.ino b/examples/ExampleReplaceRectangles/ExampleReplaceRectangles.ino new file mode 100644 index 0000000..de203de --- /dev/null +++ b/examples/ExampleReplaceRectangles/ExampleReplaceRectangles.ino @@ -0,0 +1,216 @@ +#include "arducam_dvp.h" +#include "Arduino_H7_Video.h" +#include "dsi.h" +#include "SDRAM.h" +#include "lvgl.h" +#include +#include "Arduino_GigaDisplayTouch.h" +#include "SpeeduinoGL.h" + +// This example only works with Greyscale cameras (due to the palette + resize&rotate algo) + +int YValue = 480; +// The buffer used to capture the frame +//FrameBuffer fb(SDRAM_START_ADDRESS); +float zoom = 1; +float rotation = 0; +float shifti = 400; //Horizontal +float shiftj = 240; //Vertical + +bool pause = 0; +float SafetyPixels = 0; + +//Padding arround each frame to ensure fp innaccuracies dont leave areas uncleared + +//Sensor resolution// +const int resv = 320; +const int resh = 240; + +const int ResV = 320; +const int ResH = 240; + +GDTpoint_t PreviousPoints[2]; +GDTpoint_t points[5]; + + +RectangleRasterData testRast; +RectangleRasterData testRast2; + +uint8_t contacts = 0; +uint8_t PreviousContacts = 0; + +long testvar = 0; + +//FrameBuffer outfb(SDRAM_START_ADDRESS+(320*240*2*8)); +// The buffer used to rotate and resize the frame + +FrameBuffer outfb(SDRAM_START_ADDRESS); +FrameBuffer fb(1613300736); + + +//Arduino_GigaDisplayTouch TouchDetector; + +// The buffer used to rotate and resize the frame +Arduino_H7_Video Display(800, 480, GigaDisplayShield); +GigaDisplayBacklight backlight; +Arduino_GigaDisplayTouch touchDetector; + +uint32_t palette[256]; + +void setup() { + + //FrameReady = 00000000; + SDRAM.begin(); + + + + testRast=GetRasterData(0, 0, 1, 0, 800, 480); + + + + backlight.begin(); + + Display.begin(); + + // clear the display (gives a nice black background) + dsi_lcdClear(0); + dsi_drawCurrentFrameBuffer(); + dsi_lcdClear(0); + dsi_drawCurrentFrameBuffer(); + + + for (int i = 0; i < 800; i++) { + for (int j = 0; j < 480; j++) { + + ((uint16_t*)outfb.getBuffer())[j + (i)*480] = 0x0986; + }; + }; + + + + touchDetector.begin(); + //lvll(); +} + + + +void loop() { + + int t1 = millis(); + + UpdateTouch(); + + float zoomcos = zoom * cos(rotation); + float zoomsin = zoom * sin(rotation); + + float c1 = zoomcos; + float c2 = zoomsin; + float c3 = shiftj; + float c4 = shifti; + + // Rotate the offset back to get the original camera origin position + float cameraOriginX = (c1*c1*c4 - 120*c1 + c2*(c2*c4 + 160))/(c1*c1 + c2*c2); + float cameraOriginY = (c1*c1*c3 - 160*c1 + c2*(c2*c3 - 120))/(c1*c1 + c2*c2); + + +testRast2 = GetRasterData(cameraOriginX+SafetyPixels*(cos(rotation)-sin(rotation))/zoom, cameraOriginY+SafetyPixels*(cos(rotation)+sin(rotation))/zoom, 1/zoom, rotation, ResH-2*SafetyPixels, ResV-2*SafetyPixels); //The factor added is due to FP inaccuracies +RectangleReplacement(testRast, testRast2, rand()); +testRast = GetRasterData(cameraOriginX-SafetyPixels*(cos(rotation)-sin(rotation))/zoom, cameraOriginY-SafetyPixels*(cos(rotation)+sin(rotation))/zoom, 1/zoom, rotation, ResH+2*SafetyPixels, ResV+2*SafetyPixels); //The factor added is due to FP inaccuracies + +//do the maths tommorow + + dsi_lcdDrawImage((void*)outfb.getBuffer(), (void*)dsi_getCurrentFrameBuffer(), 480, 800, DMA2D_INPUT_RGB565); + + + dsi_drawCurrentFrameBuffer(); + + + + + Serial.println(millis() - t1); +} + + +void UpdateTouch() { + + + PreviousPoints[0] = points[0]; + PreviousPoints[1] = points[1]; + PreviousContacts = contacts; + contacts = touchDetector.getTouchPoints(points); + + if (contacts == 1 && PreviousContacts == 1) { +shifti += points[0].x - PreviousPoints[0].x; +shiftj += points[0].y - PreviousPoints[0].y; + }; + +if (contacts == 2 && PreviousContacts == 2) { + float currentMidX = (points[0].x + points[1].x) / 2.0; + float currentMidY = (points[0].y + points[1].y) / 2.0; + float previousMidX = (PreviousPoints[0].x + PreviousPoints[1].x) / 2.0; + float previousMidY = (PreviousPoints[0].y + PreviousPoints[1].y) / 2.0; + + // Calculate the shift based on the movement of the midpoints + shifti += (currentMidX - previousMidX); + shiftj += (currentMidY - previousMidY); + + // Calculate the zoom factor + double zoomfactor = sqrt(sq(points[0].x - points[1].x) + sq(points[0].y - points[1].y)) / + sqrt(sq(PreviousPoints[0].x - PreviousPoints[1].x) + sq(PreviousPoints[0].y - PreviousPoints[1].y)); + + // Adjust shift values based on the zoom factor and the midpoint + shifti = currentMidX + (shifti - currentMidX) * zoomfactor; + shiftj = currentMidY + (shiftj - currentMidY) * zoomfactor; + + // Update the zoom + zoom /= zoomfactor; + + // Calculate the angle between the lines formed by the points + float currentAngle = atan2(points[1].y - points[0].y, points[1].x - points[0].x); + float previousAngle = atan2(PreviousPoints[1].y - PreviousPoints[0].y, PreviousPoints[1].x - PreviousPoints[0].x); + + // Calculate the rotation change + float rotationM = currentAngle - previousAngle; + + // Normalize rotationM to be within -PI to PI + if (rotationM > PI) { + rotationM -= 2 * PI; + } else if (rotationM < -PI) { + rotationM += 2 * PI; + } + + // Apply the rotation change + rotation += rotationM; + + // Calculate the rotation point relative to the midpoint + float rotationPointX = shifti - currentMidX; + float rotationPointY = shiftj - currentMidY; + + // Rotate the rotation point + float rotatedRotationPointX = rotationPointX * cos(rotationM) - rotationPointY * sin(rotationM); + float rotatedRotationPointY = rotationPointX * sin(rotationM) + rotationPointY * cos(rotationM); + + // Adjust the shift values based on the rotated rotation point and the midpoint + shifti = currentMidX + rotatedRotationPointX; + shiftj = currentMidY + rotatedRotationPointY; +}; + +if (contacts == 3 && PreviousContacts == 3) { +zoom = 1; +rotation = 0; +shifti = 400; //Horizontal +shiftj = 240; //Vertical +}; + +if (contacts == 4 && PreviousContacts != 4) { +if (pause == 0) { +pause = 1; +} else { +pause = 0; +}; +}; + +//Serial.println(shiftj); +//Serial.println(zoom); + +} \ No newline at end of file diff --git a/examples/GigaR1CameraFeedGestureTrasnsformFinal/GigaR1CameraFeedGestureTrasnsformFinal.ino b/examples/GigaR1CameraFeedGestureTrasnsformFinal/GigaR1CameraFeedGestureTrasnsformFinal.ino new file mode 100644 index 0000000..66863b1 --- /dev/null +++ b/examples/GigaR1CameraFeedGestureTrasnsformFinal/GigaR1CameraFeedGestureTrasnsformFinal.ino @@ -0,0 +1,272 @@ +#include "arducam_dvp.h" +#include "Arduino_H7_Video.h" +#include "dsi.h" +#include "SDRAM.h" +#include "lvgl.h" +#include +#include "Arduino_GigaDisplayTouch.h" +#include "SpeeduinoGL.h" + +// This example only works with Greyscale cameras (due to the palette + resize&rotate algo) +#define ARDUCAM_CAMERA_OV767X + +#ifdef ARDUCAM_CAMERA_OV767X +#include "OV7670/ov767x.h" +// OV7670 ov767x; +OV7670 ov767x; +Camera cam(ov767x); +#define IMAGE_MODE CAMERA_RGB565 +#endif +int YValue = 480; +// The buffer used to capture the frame +//FrameBuffer fb(SDRAM_START_ADDRESS); +float zoom = 1; +float rotation = 0; +float shifti = 400; //Horizontal +float shiftj = 240; //Vertical + +bool pause = 0; +float SafetyPixels = 0.01; + +//Padding arround each frame to ensure fp innaccuracies dont leave areas uncleared + +//Sensor resolution// +const int resv = 320; +const int resh = 240; + +const int ResV = 320; +const int ResH = 240; + +GDTpoint_t PreviousPoints[2]; +GDTpoint_t points[5]; + + +RectangleRasterData testRast; +RectangleRasterData testRast2; + +uint8_t contacts = 0; +uint8_t PreviousContacts = 0; + +long testvar = 0; + +//FrameBuffer outfb(SDRAM_START_ADDRESS+(320*240*2*8)); +// The buffer used to rotate and resize the frame + +FrameBuffer outfb(SDRAM_START_ADDRESS); +FrameBuffer fb(1613300736); + + +//Arduino_GigaDisplayTouch TouchDetector; + +// The buffer used to rotate and resize the frame +Arduino_H7_Video Display(800, 480, GigaDisplayShield); +GigaDisplayBacklight backlight; +Arduino_GigaDisplayTouch touchDetector; + +uint32_t palette[256]; + +void setup() { + + //FrameReady = 00000000; + SDRAM.begin(); + + if (!cam.begin(CAMERA_R320x240, IMAGE_MODE, 60)) { + }; + + testRast=GetRasterData(0, 0, 1, 0, 800, 480); + + + + backlight.begin(); + + Display.begin(); + + // clear the display (gives a nice black background) + dsi_lcdClear(0); + dsi_drawCurrentFrameBuffer(); + dsi_lcdClear(0); + dsi_drawCurrentFrameBuffer(); + + + for (int i = 0; i < 800; i++) { + for (int j = 0; j < 480; j++) { + + ((uint16_t*)outfb.getBuffer())[j + (i)*480] = 0x0986; + }; + }; + + + + touchDetector.begin(); + //lvll(); +} + + +#define HTONS(x) (((x >> 8) & 0x00FF) | ((x << 8) & 0xFF00)) + +void loop() { + + int t1 = millis(); + + + //* Grab frame and write to another framebuffer + + + if (pause == 0) { + +cam.grabFrame(fb, 3000); + + }; + + + UpdateTouch(); + + float zoomcos = zoom * cos(rotation); + float zoomsin = zoom * sin(rotation); + + + +if(zoom>0.2) { + + for (int i = 0; i < 800; i++) { + + for (int j = 0; j < 480; j++) { + int nearestj = ((j - shiftj) * zoomcos) - ((i - shifti) * zoomsin); + int nearesti = ((i - shifti) * zoomcos) + ((j - shiftj) * zoomsin); + int pc2 = (nearestj + (nearesti)*resv); + int pc = j + ((i)) * 480; + if (nearesti < resh/2 && nearestj < resv/2 && nearesti > -resh/2 && nearestj > -resv/2) { + ((uint16_t*)outfb.getBuffer())[pc] = HTONS(((uint16_t*)fb.getBuffer())[pc2 + resh*resv/2 + resv/2]); + } else { + ((uint16_t*)outfb.getBuffer())[pc] = 0x0986; + }; + } + }; +} else { + // FillScreen(0); + + /// int nearestj = ((j - shiftj) * zoomcos) - ((i - shifti) * zoomsin); + // int nearesti = ((i - shifti) * zoomcos) + ((j - shiftj) * zoomsin); + + + // 120 = ((y - c3) * c1) - ((x - c4) * c2); + //160 = ((x - c4) * c1) + ((y - c3) * c2); + + float c1 = zoomcos; + float c2 = zoomsin; + float c3 = shiftj; + float c4 = shifti; + + // Rotate the offset back to get the original camera origin position + float cameraOriginX = (c1*c1*c4 - 120*c1 + c2*(c2*c4 + 160))/(c1*c1 + c2*c2); + float cameraOriginY = (c1*c1*c3 - 160*c1 + c2*(c2*c3 - 120))/(c1*c1 + c2*c2); + + +testRast2 = GetRasterData(cameraOriginX+SafetyPixels*(cos(rotation)-sin(rotation))/zoom, cameraOriginY+SafetyPixels*(cos(rotation)+sin(rotation))/zoom, 1/zoom, rotation, ResH-2*SafetyPixels, ResV-2*SafetyPixels); //The factor added is due to FP inaccuracies + + + + RectangleReplacement(testRast, testRast2, 0x0986); + + TransferSquares(cameraOriginX, cameraOriginY, 1 / zoom, rotation); + + +testRast = GetRasterData(cameraOriginX-SafetyPixels*(cos(rotation)-sin(rotation))/zoom, cameraOriginY-SafetyPixels*(cos(rotation)+sin(rotation))/zoom, 1/zoom, rotation, ResH+2*SafetyPixels, ResV+2*SafetyPixels); //The factor added is due to FP inaccuracies +}; +//do the maths tommorow + + dsi_lcdDrawImage((void*)outfb.getBuffer(), (void*)dsi_getCurrentFrameBuffer(), 480, 800, DMA2D_INPUT_RGB565); + + + dsi_drawCurrentFrameBuffer(); + + + + + Serial.println(millis() - t1); +} + + +void UpdateTouch() { + + + PreviousPoints[0] = points[0]; + PreviousPoints[1] = points[1]; + PreviousContacts = contacts; + contacts = touchDetector.getTouchPoints(points); + + if (contacts == 1 && PreviousContacts == 1) { +shifti += points[0].x - PreviousPoints[0].x; +shiftj += points[0].y - PreviousPoints[0].y; + }; + +if (contacts == 2 && PreviousContacts == 2) { + float currentMidX = (points[0].x + points[1].x) / 2.0; + float currentMidY = (points[0].y + points[1].y) / 2.0; + float previousMidX = (PreviousPoints[0].x + PreviousPoints[1].x) / 2.0; + float previousMidY = (PreviousPoints[0].y + PreviousPoints[1].y) / 2.0; + + // Calculate the shift based on the movement of the midpoints + shifti += (currentMidX - previousMidX); + shiftj += (currentMidY - previousMidY); + + // Calculate the zoom factor + double zoomfactor = sqrt(sq(points[0].x - points[1].x) + sq(points[0].y - points[1].y)) / + sqrt(sq(PreviousPoints[0].x - PreviousPoints[1].x) + sq(PreviousPoints[0].y - PreviousPoints[1].y)); + + // Adjust shift values based on the zoom factor and the midpoint + shifti = currentMidX + (shifti - currentMidX) * zoomfactor; + shiftj = currentMidY + (shiftj - currentMidY) * zoomfactor; + + // Update the zoom + zoom /= zoomfactor; + + // Calculate the angle between the lines formed by the points + float currentAngle = atan2(points[1].y - points[0].y, points[1].x - points[0].x); + float previousAngle = atan2(PreviousPoints[1].y - PreviousPoints[0].y, PreviousPoints[1].x - PreviousPoints[0].x); + + // Calculate the rotation change + float rotationM = currentAngle - previousAngle; + + // Normalize rotationM to be within -PI to PI + if (rotationM > PI) { + rotationM -= 2 * PI; + } else if (rotationM < -PI) { + rotationM += 2 * PI; + } + + // Apply the rotation change + rotation += rotationM; + + // Calculate the rotation point relative to the midpoint + float rotationPointX = shifti - currentMidX; + float rotationPointY = shiftj - currentMidY; + + // Rotate the rotation point + float rotatedRotationPointX = rotationPointX * cos(rotationM) - rotationPointY * sin(rotationM); + float rotatedRotationPointY = rotationPointX * sin(rotationM) + rotationPointY * cos(rotationM); + + // Adjust the shift values based on the rotated rotation point and the midpoint + shifti = currentMidX + rotatedRotationPointX; + shiftj = currentMidY + rotatedRotationPointY; +}; + +if (contacts == 3 && PreviousContacts == 3) { +zoom = 1; +rotation = 0; +shifti = 400; //Horizontal +shiftj = 240; //Vertical +}; + +if (contacts == 4 && PreviousContacts != 4) { +if (pause == 0) { +pause = 1; +} else { +pause = 0; +}; +}; + +//Serial.println(shiftj); +//Serial.println(zoom); + +} \ No newline at end of file diff --git a/library.properties b/library.properties index c45774f..d9fcc61 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=SpeeduinoGL -version=0.0.5 +version=0.0.79 author=Benjamin Gombala maintainer=Benjamin Gombala benjamin.gombala@gmail.com Bexin sentence=A library with basic graphical functions optimised for arm cortex m7. diff --git a/src/SpeeduinoGL.cpp b/src/SpeeduinoGL.cpp index 2fdcdfb..fc39f4b 100644 --- a/src/SpeeduinoGL.cpp +++ b/src/SpeeduinoGL.cpp @@ -34,9 +34,9 @@ void FillScreen(uint16_t Colour) { } ); - float gradAC = (triangle.A.h - triangle.C.h) / (triangle.A.w - triangle.C.w); - float gradAB = (triangle.A.h - triangle.B.h) / (triangle.A.w - triangle.B.w); - float gradBC = (triangle.B.h - triangle.C.h) / (triangle.B.w - triangle.C.w); + float gradAC = (triangle.C.h - triangle.A.h) / (triangle.C.w - triangle.A.w); + float gradAB = (triangle.B.h - triangle.A.h) / (triangle.B.w - triangle.A.w); + float gradBC = (triangle.C.h - triangle.B.h) / (triangle.C.w - triangle.B.w); bool Polarized = gradAB > gradAC; @@ -136,7 +136,6 @@ DoubleFloat PolarizedTwoLineRasterizer(int32_t CellStartX, int32_t CellEndX, flo } - DoubleFloat TwoLineRasterizer(int32_t CellStartX, int32_t CellEndX, float PointerCoordinateH, float PointerEndH, float Gradient1, float Gradient2, uint16_t Colour) { @@ -269,30 +268,11 @@ void TransferSquares(float ShiftH, float ShiftV, float zoom, float rotationRad) float grad2; - - float offsetH1 = abs(VShift); - float offsetH2 = abs(HShift); - float offsetV1 = abs(VShift) + abs(HShift); - float offsetV2 = 0; - - - bool Polarized = 0; - - - if (sin(rotationRad) <= 0) { - std::swap(offsetH1, offsetH2); - std::swap(offsetV1, offsetV2); - - }; - if (sin(2 * rotationRad) <= 0) { std::swap(gradient1, gradient2); - std::swap(offsetH2, offsetV1); - std::swap(offsetH1, offsetV2); - }; if (sin(4 * rotationRad) <= 0) { @@ -308,23 +288,11 @@ void TransferSquares(float ShiftH, float ShiftV, float zoom, float rotationRad) float CellPointerH = ShiftH; float CellPointerV = ShiftV; - - //rotationRad+=PI/4; - //zoom /= sqrt(2); - - float BoundStartH = - offsetH1; - float BoundEndH = ResH + offsetH2; - float BoundStartV = - offsetV1; - float BoundEndV = ResV + offsetV2; - - // float InsideStartH = -1 + offsetH2; - // float InsideEndH = ResH - offsetH1; - // float InsideStartV = -1 + offsetV2; - // float InsideEndV = ResV - offsetV1; - - - + const float BoundStartH = 0 - zoom - abs(VShift); + const float BoundStartV = 0 - zoom - abs(HShift); + const float BoundEndH = ResH + zoom + abs(VShift); + const float BoundEndV = ResV + zoom + abs(HShift); bool RowsPassed = 0; @@ -387,32 +355,25 @@ void TransferSquares(float ShiftH, float ShiftV, float zoom, float rotationRad) }; - - - - - DoubleFloat WouldWork = - PolarizedTwoLineRasterizer(ceil(square.A.w), ceil(square.B.w), - square.A.h + grad2 * (ceil(square.A.w) - square.A.w), - square.A.h + grad1 * (ceil(square.A.w) - square.A.w), - grad1, grad2, Colour, Polarized); - - if (Polarized) { std::swap(WouldWork.Float1, WouldWork.Float2); }; - WouldWork = - PolarizedTwoLineRasterizer(ceil(square.B.w), ceil(square.D.w), - WouldWork.Float2, - square.B.h + grad2 * (ceil(square.B.w) - square.B.w), - grad2, grad2, Colour, Polarized); - - if (Polarized) { std::swap(WouldWork.Float1, WouldWork.Float2); }; - PolarizedTwoLineRasterizer(ceil(square.D.w), ceil(square.C.w), - square.D.h + grad1 * (ceil(square.D.w) - square.D.w), - WouldWork.Float1, - grad2, grad1, Colour, Polarized); - - - - + DoubleFloat WouldWork = + PolarizedTwoLineRasterizer(ceil(square.A.w), ceil(square.B.w), + square.A.h + grad2 * (ceil(square.A.w) - square.A.w), + square.A.h + grad1 * (ceil(square.A.w) - square.A.w), + grad1, grad2, Colour, Polarized); + + if (Polarized) { std::swap(WouldWork.Float1, WouldWork.Float2); }; + WouldWork = + PolarizedTwoLineRasterizer(ceil(square.B.w), ceil(square.D.w), + WouldWork.Float2, + square.B.h + grad2 * (ceil(square.B.w) - square.B.w), + grad2, grad2, Colour, Polarized); + + if (Polarized) { std::swap(WouldWork.Float1, WouldWork.Float2); }; + PolarizedTwoLineRasterizer(ceil(square.D.w), ceil(square.C.w), + square.D.h + grad1 * (ceil(square.D.w) - square.D.w), + WouldWork.Float1, + grad2, grad1, Colour, Polarized); + } else if (BoundaryPassed == 1) { goto ByPassROLine; @@ -452,3 +413,369 @@ void TransferSquares(float ShiftH, float ShiftV, float zoom, float rotationRad) + +void RectangleReplacement(RectangleRasterData Past, RectangleRasterData New, uint16_t Colour) { +//you might see !(Past.RectangleBottomX <= 0), yes its weird but it seems for some reason > for two signed numbers is currently broken for Giga R1 and causes issues when one number is negative. + + uint16_t* ImageBuffer = (uint16_t*)ImageAddress; + + + + if (Past.RectangleStartX < 0) { + if (Past.RectangleEndX < 0) { + goto returnpoint; + } else { + if (!(Past.RectangleBottomX <= 0)) { + Past.RectangleFirstBottomY -= Past.RectangleFirstBottomGradient * Past.RectangleStartX; + } else { + Past.RectangleSecondBottomY -= Past.RectangleSecondBottomGradient * Past.RectangleBottomX; + Past.RectangleBottomX = 0; + }; + if (!(Past.RectangleTopX <= 0)) { + Past.RectangleFirstTopY -= Past.RectangleFirstTopGradient * Past.RectangleStartX; + } else { + Past.RectangleSecondTopY -= Past.RectangleSecondTopGradient * Past.RectangleTopX; + Past.RectangleTopX = 0; + } + Past.RectangleStartX = 0; + }; + }; + + + if (!(Past.RectangleStartX <= New.RectangleStartX) && !(New.RectangleEndX <= Past.RectangleStartX)) { + + if (!(New.RectangleBottomX <= Past.RectangleStartX)) { + New.RectangleFirstBottomY -= New.RectangleFirstBottomGradient * (New.RectangleStartX-Past.RectangleStartX); + } else { + New.RectangleSecondBottomY -= New.RectangleSecondBottomGradient * (New.RectangleBottomX-Past.RectangleStartX); + New.RectangleBottomX = Past.RectangleStartX; + }; + if (!(New.RectangleTopX <= Past.RectangleStartX)) { + New.RectangleFirstTopY -= New.RectangleFirstTopGradient * (New.RectangleStartX-Past.RectangleStartX); + } else { + New.RectangleSecondTopY -= New.RectangleSecondTopGradient * (New.RectangleTopX-Past.RectangleStartX); + New.RectangleTopX = Past.RectangleStartX; + } + New.RectangleStartX = Past.RectangleStartX; + + }; + + + if (New.RectangleStartX < Past.RectangleStartX) { + New.RectangleStartX = Past.RectangleStartX; + }; + + + if (New.RectangleEndX < New.RectangleStartX) { + New.RectangleEndX = New.RectangleStartX; + }; + + + + + if (Past.RectangleEndX > ResH) { + Past.RectangleEndX = ResH; + if (Past.RectangleStartX > ResH) { + goto returnpoint; + }; + }; + + + if (Past.RectangleEndX < New.RectangleEndX) { + New.RectangleEndX = Past.RectangleEndX; + }; + + if (New.RectangleEndX < New.RectangleStartX) { + New.RectangleStartX = New.RectangleEndX; + }; + + + + + + +for (uint32_t CurrentW = Past.RectangleStartX; New.RectangleStartX > CurrentW; CurrentW++) { + + + int32_t PointerCoorInt; + int32_t PointerEndInt; + + +if (CurrentW ResV) { + PointerEndInt = ResV; + }; + + if (PointerCoorInt > ResV) { + PointerCoorInt = ResV; + }; + + + for (uint32_t CurrentH = PointerCoorInt; PointerEndInt > CurrentH; CurrentH++) { + ImageBuffer[ResV * (CurrentW) + (CurrentH)] = Colour; + }; + + +}; + + + + + + + + + + for (uint32_t CurrentW = New.RectangleStartX; New.RectangleEndX > CurrentW; CurrentW++) { + + int32_t PointerCoorInt; + int32_t PointerEndInt; + int32_t SubCoorInt; + int32_t SubEndInt; + + if (CurrentW ResV) { + PointerEndInt = ResV; + }; + + if (PointerCoorInt > ResV) { + PointerCoorInt = ResV; + }; + + + bool State = 0; + if (SubEndInt>SubCoorInt) { + if (SubCoorIntPointerCoorInt) { + State = 1; + }; + + + + }; + + + + if (SubCoorInt>ResV) { + SubCoorInt=ResV;}; + + + if (SubEndInt>ResV) {SubEndInt=ResV;}; + + + + if (State) { + for (uint32_t CurrentH = PointerCoorInt; SubCoorInt > CurrentH; CurrentH++) { + ImageBuffer[ResV * (CurrentW) + (CurrentH)] = Colour; + }; + for (uint32_t CurrentH = SubEndInt; PointerEndInt > CurrentH; CurrentH++) { + ImageBuffer[ResV * (CurrentW) + (CurrentH)] = Colour; + }; + } else { + for (uint32_t CurrentH = PointerCoorInt; PointerEndInt > CurrentH; CurrentH++) { + ImageBuffer[ResV * (CurrentW) + (CurrentH)] = Colour; + }; + }; + + + +}; + + + + + +for (uint32_t CurrentW = New.RectangleEndX; Past.RectangleEndX > CurrentW; CurrentW++) { + + + int32_t PointerCoorInt; + int32_t PointerEndInt; + + +if (CurrentW ResV) { + PointerEndInt = ResV; + }; + + if (PointerCoorInt > ResV) { + PointerCoorInt = ResV; + }; + + + for (uint32_t CurrentH = PointerCoorInt; PointerEndInt > CurrentH; CurrentH++) { + ImageBuffer[ResV * (CurrentW) + (CurrentH)] = Colour; + }; + + +}; + + + + + returnpoint: + (1); + + } + + +RectangleRasterData GetRasterData(float ShiftH, float ShiftV, float zoom, float rotationRad, float InputH, float InputV) { + + RectangleRasterData RasterDataOutput; + + //A left start + //B top + //D bottom + //C right end + + Rectangle rectangle = { + { ShiftH, ShiftV }, + { ShiftH + zoom*InputH*cos(rotationRad), ShiftV + zoom*InputH*sin(rotationRad)}, + { ShiftH - zoom*InputV*sin(rotationRad), ShiftV + zoom*InputV*cos(rotationRad) }, + { ShiftH + zoom*InputH*cos(rotationRad) - zoom*InputV*sin(rotationRad), ShiftV + zoom*InputH*sin(rotationRad) + zoom*InputV*cos(rotationRad)} + }; + + //zoom*InputV*cos(rotationRad)+ + + + //zoom*InputH*cos(rotationRad) + + std::sort(&rectangle.A, &rectangle.C + 1, + [](const Point &a, const Point &b) { + return a.w < b.w; + } + ); + + if (rectangle.D.h>rectangle.B.h) { + std::swap(rectangle.D, rectangle.B); + }; + + + + RasterDataOutput.RectangleStartX = ceil(rectangle.A.w); + RasterDataOutput.RectangleEndX = ceil(rectangle.C.w); + RasterDataOutput.RectangleBottomX = ceil(rectangle.D.w); + RasterDataOutput.RectangleTopX = ceil(rectangle.B.w); + + RasterDataOutput.RectangleFirstBottomGradient=(rectangle.D.h-rectangle.A.h)/(rectangle.D.w-rectangle.A.w); + RasterDataOutput.RectangleSecondBottomGradient=(rectangle.C.h-rectangle.D.h)/(rectangle.C.w-rectangle.D.w); + + + RasterDataOutput.RectangleFirstTopGradient=(rectangle.B.h-rectangle.A.h)/(rectangle.B.w-rectangle.A.w); + RasterDataOutput.RectangleSecondTopGradient=(rectangle.C.h-rectangle.B.h)/(rectangle.C.w-rectangle.B.w); + + RasterDataOutput.RectangleFirstBottomY = rectangle.A.h + RasterDataOutput.RectangleFirstBottomGradient * (ceil(rectangle.A.w) - rectangle.A.w); + RasterDataOutput.RectangleSecondBottomY = rectangle.D.h + RasterDataOutput.RectangleSecondBottomGradient * (ceil(rectangle.D.w) - rectangle.D.w); + + RasterDataOutput.RectangleFirstTopY = rectangle.A.h + RasterDataOutput.RectangleFirstTopGradient * (ceil(rectangle.A.w) - rectangle.A.w); + RasterDataOutput.RectangleSecondTopY = rectangle.B.h + RasterDataOutput.RectangleSecondTopGradient * (ceil(rectangle.B.w) - rectangle.B.w); + + + return(RasterDataOutput); +} + + + diff --git a/src/SpeeduinoGL.h b/src/SpeeduinoGL.h index 5e5bbf6..7cd1c72 100644 --- a/src/SpeeduinoGL.h +++ b/src/SpeeduinoGL.h @@ -27,6 +27,18 @@ struct DoubleFloat { Point C; }; +struct RectangleRasterData { + int32_t RectangleStartX; int32_t RectangleEndX; + + int32_t RectangleBottomX; int32_t RectangleTopX; + + float RectangleFirstBottomY; float RectangleSecondBottomY; + float RectangleFirstBottomGradient; float RectangleSecondBottomGradient; + + float RectangleFirstTopY; float RectangleSecondTopY; + float RectangleFirstTopGradient; float RectangleSecondTopGradient; +}; + @@ -42,9 +54,12 @@ DoubleFloat PolarizedTwoLineRasterizer(int32_t CellStartX, int32_t CellEndX, flo __attribute__((always_inline)) DoubleFloat TwoLineRasterizer(int32_t CellStartX, int32_t CellEndX, float PointerCoordinateH, float PointerEndH, float Gradient1, float Gradient2, uint16_t Colour); - -void FillCircle(float Radius, uint16_t Colour, Point Centre); + void FillCircle(float Radius, uint16_t Colour, Point Centre); void TransferSquares(float ShiftH, float ShiftV, float zoom, float rotationRad); +void RectangleReplacement(RectangleRasterData Past, RectangleRasterData New, uint16_t Colour); + +RectangleRasterData GetRasterData(float ShiftH, float ShiftV, float zoom, float rotationRad, float InputH, float InputV); + #endif