mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[python] merge '6fcab395' and fix a bug in fill_polygon()
This commit is contained in:
@@ -3,8 +3,10 @@ SFLAGS += -Ikandinsky/include
|
||||
kandinsky_src += $(addprefix kandinsky/src/,\
|
||||
color.cpp \
|
||||
context.cpp \
|
||||
context_circle.cpp \
|
||||
context_line.cpp \
|
||||
context_pixel.cpp \
|
||||
context_polygon.cpp \
|
||||
context_rect.cpp \
|
||||
context_text.cpp \
|
||||
font.cpp \
|
||||
|
||||
@@ -28,6 +28,10 @@ public:
|
||||
// Line. Not anti-aliased.
|
||||
void drawLine(KDPoint p1, KDPoint p2, KDColor c);
|
||||
|
||||
// Circle
|
||||
void drawCircle(KDPoint c, KDCoordinate r, KDColor color);
|
||||
void fillCircle(KDPoint c, KDCoordinate r, KDColor color);
|
||||
|
||||
// Rect
|
||||
void fillRect(KDRect rect, KDColor color);
|
||||
void fillRectWithPixels(KDRect rect, const KDColor * pixels, KDColor * workingBuffer);
|
||||
@@ -36,6 +40,10 @@ public:
|
||||
virtual void pushRect(KDRect, const KDColor * pixels) = 0;
|
||||
virtual void pushRectUniform(KDRect rect, KDColor color) = 0;
|
||||
virtual void pullRect(KDRect rect, KDColor * pixels) = 0;
|
||||
|
||||
//Polygon
|
||||
static const int k_polygonMaxNumberOfPoints = 32;
|
||||
void fillPolygon(KDCoordinate pointsX[], KDCoordinate pointsY[], int numberOfPoints, KDColor color);
|
||||
protected:
|
||||
KDContext(KDPoint origin, KDRect clippingRect);
|
||||
private:
|
||||
|
||||
49
kandinsky/src/context_circle.cpp
Normal file
49
kandinsky/src/context_circle.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <kandinsky/context.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
void KDContext::drawCircle(KDPoint c, KDCoordinate r, KDColor color) {
|
||||
|
||||
//The used algorithm is the Bresenham's arc tracing algorithm
|
||||
|
||||
KDCoordinate x, y, m;
|
||||
x = 0;
|
||||
y = r;
|
||||
m = 5 - 4*r;
|
||||
|
||||
while(x <= y) {
|
||||
setPixel(c.translatedBy(KDPoint(x,y)), color);
|
||||
setPixel(c.translatedBy(KDPoint(y,x)), color);
|
||||
setPixel(c.translatedBy(KDPoint(-x,y)), color);
|
||||
setPixel(c.translatedBy(KDPoint(-y,x)), color);
|
||||
setPixel(c.translatedBy(KDPoint(x,-y)), color);
|
||||
setPixel(c.translatedBy(KDPoint(y,-x)), color);
|
||||
setPixel(c.translatedBy(KDPoint(-x,-y)), color);
|
||||
setPixel(c.translatedBy(KDPoint(-y,-x)), color);
|
||||
|
||||
if(m > 0) {
|
||||
y = y - 1;
|
||||
m = m - 8*y;
|
||||
}
|
||||
|
||||
x = x + 1;
|
||||
m = m + 8*x + 4;
|
||||
}
|
||||
}
|
||||
|
||||
void KDContext::fillCircle(KDPoint c, KDCoordinate r, KDColor color) {
|
||||
KDCoordinate left = c.x()-r;
|
||||
KDCoordinate right = c.x()+r;
|
||||
if(left < 0) {
|
||||
left = 0;
|
||||
}
|
||||
if(right > m_clippingRect.width()) {
|
||||
right = m_clippingRect.width();
|
||||
}
|
||||
|
||||
for(KDCoordinate x=left; x<=right; x++) {
|
||||
KDCoordinate semiHeight = sqrt((r*r)-((c.x()-x)*(c.x()-x)));
|
||||
|
||||
fillRect(KDRect(x, c.y()-semiHeight, 1, semiHeight * 2 ), color);
|
||||
}
|
||||
}
|
||||
67
kandinsky/src/context_polygon.cpp
Normal file
67
kandinsky/src/context_polygon.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include <kandinsky/context.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
void KDContext::fillPolygon(KDCoordinate pointsX[], KDCoordinate pointsY[], int numberOfPoints, KDColor color)
|
||||
{
|
||||
//The used algorithm is the scan-line algorithm
|
||||
|
||||
KDCoordinate top = KDCOORDINATE_MAX;
|
||||
KDCoordinate bottom = KDCOORDINATE_MIN;
|
||||
KDCoordinate right = m_clippingRect.width();
|
||||
KDCoordinate left = 0;
|
||||
|
||||
for (int i = 0; i < numberOfPoints; i++) {
|
||||
if (pointsY[i] < top) {
|
||||
top = pointsY[i];
|
||||
}
|
||||
if (pointsY[i] > bottom) {
|
||||
bottom = pointsY[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (top < 0) {
|
||||
top = 0;
|
||||
}
|
||||
if (bottom > m_clippingRect.height()) {
|
||||
bottom = m_clippingRect.height();
|
||||
}
|
||||
|
||||
|
||||
for (int y=top; y<=bottom; y++) {
|
||||
|
||||
int switches=0;
|
||||
KDCoordinate switchesX[KDContext::k_polygonMaxNumberOfPoints];
|
||||
int lastPointIndex = numberOfPoints-1;
|
||||
|
||||
for (int i=0; i<numberOfPoints; i++) {
|
||||
if (((pointsY[i]<=y && pointsY[lastPointIndex]>=y) || (pointsY[lastPointIndex]<= y && pointsY[i]>=y)) && pointsY[i] != pointsY[lastPointIndex]) {
|
||||
switchesX[switches++] = (int) round(pointsX[i]+1.0*(y-pointsY[i])/(pointsY[lastPointIndex]-pointsY[i])*(pointsX[lastPointIndex]-pointsX[i]));
|
||||
}
|
||||
lastPointIndex=i;
|
||||
}
|
||||
|
||||
//Sorting switches by a bubble sort
|
||||
int i=0;
|
||||
while (i<switches-1) {
|
||||
if (switchesX[i]>switchesX[i+1]) {
|
||||
KDCoordinate temp = switchesX[i];
|
||||
switchesX[i]=switchesX[i+1];
|
||||
switchesX[i+1]=temp;
|
||||
if (i) i--;
|
||||
}
|
||||
else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<switches; i+=2) {
|
||||
if (switchesX[i]>=right) {
|
||||
break;
|
||||
}
|
||||
if (switchesX[i+1]>left) {
|
||||
fillRect( KDRect( switchesX[ i ] , y, switchesX[ i+1 ] - switchesX[ i ], 1 ), color ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user