From bb405a41381b69f9c217c9fa9a2addfdf32b3b71 Mon Sep 17 00:00:00 2001 From: blobt <380255922@qq.com> Date: Wed, 29 Jan 2020 09:45:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=92=E7=BA=BF=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Rester.cc | 144 +++++++++++++++++++++++++++++++++++++++++++++++-- src/Rester.h | 14 ++++- src/Rgba.h | 11 ++++ src/common.h | 44 ++++++++++++--- src/gtktest.cc | 34 ++++++++++-- src/tt.cc | 37 +++++++++---- 6 files changed, 258 insertions(+), 26 deletions(-) diff --git a/src/Rester.cc b/src/Rester.cc index 65e25d0..523d41c 100644 --- a/src/Rester.cc +++ b/src/Rester.cc @@ -16,6 +16,7 @@ #include #include #include +#include using namespace std; @@ -30,7 +31,7 @@ Rester::~Rester() { delete buffer; } -void Rester::drawPointer(int x, int y, Rgba color, int pointSize) { +void Rester::drawPoint(int x, int y, Rgba color, int pointSize) { switch (pointSize) { case 1: setPixel(x, y, color); @@ -54,6 +55,143 @@ void Rester::drawPointer(int x, int y, Rgba color, int pointSize) { } } +void Rester::drawLine(float2 p1, float2 p2, Rgba color) { + + float xOffer = p1.x - p2.x; + float yOffer = p1.y - p2.y; + float xStart, xEnd, yStart, yEnd; + + if (xOffer == 0 && yOffer == 0) { + setPixel(p1.x, p1.y, color); + } + + + if (fabs(xOffer) > fabs(yOffer)) { + if (p1.x < p2.x) { + xStart = p1.x; + xEnd = p2.x; + yEnd = p2.y; + } else { + xStart = p2.x; + xEnd = p1.x; + yEnd = p1.y; + } + + float slope = yOffer / xOffer; + for (float i = xStart; i < xEnd; i += 1.0) { + float q = yEnd - slope * (xEnd - i); + setPixel(i, q, color); + } + } else { + if (p1.y < p2.y) { + yStart = p1.y; + yEnd = p2.y; + xEnd = p2.x; + } else { + yStart = p2.y; + yEnd = p1.y; + xEnd = p1.x; + } + float slope = xOffer / yOffer; + for (float i = yStart; i < yEnd; i += 1.0) { + float q = xEnd - slope * (yEnd - i); + setPixel(q, i, color); + } + } + +} + +void Rester::drawLine(float2 p1, float2 p2, Rgba color1, Rgba color2) { + + float xOffer = p1.x - p2.x; + float yOffer = p1.y - p2.y; + float xStart, xEnd, yStart, yEnd, step; + + if (xOffer == 0 && yOffer == 0) { + setPixel(p1.x, p1.y, color1); + } + + + if (fabs(xOffer) > fabs(yOffer)) { + if (p1.x < p2.x) { + xStart = p1.x; + xEnd = p2.x; + yEnd = p2.y; + } else { + xStart = p2.x; + xEnd = p1.x; + yEnd = p1.y; + } + + float slope = yOffer / xOffer; + float length = xEnd - xStart; + + for (float i = xStart; i < xEnd; i += 1.0) { + float q = yEnd - slope * (xEnd - i); + step = (i - xStart) / length; + Rgba color = colorLerp(color1, color2, step); + setPixel(i, q, color); + } + } else { + if (p1.y < p2.y) { + yStart = p1.y; + yEnd = p2.y; + xEnd = p2.x; + } else { + yStart = p2.y; + yEnd = p1.y; + xEnd = p1.x; + } + float slope = xOffer / yOffer; + float length = yEnd - yStart; + for (float i = yStart; i < yEnd; i += 1.0) { + float q = xEnd - slope * (yEnd - i); + step = (i - yStart) / length; + Rgba color = colorLerp(color1, color2, step); + setPixel(q, i, color); + } + } + +} + +void Rester::drawArray(DRAWMODE mode, const float2* points, size_t count) { + switch (mode) { + case DM_POINTS: + { + for (size_t i = 0; i < count; i++) { + drawPoint(points[0].x, points[1].y); + } + } + break; + case DM_LINES: + { + count = count / 2 * 2; //保证其为2的倍数 + for (size_t i = 0; i < count; i++) { + drawLine(points[i], points[i + 1]); + } + } + break; + case DM_LINES_LOOP: + { + size_t i = count; + drawLine(points[0], points[1]); + for (i = 2; i < count; i++) { + drawLine(points[i - 1], points[i]); + } + drawLine(points[0], points[i]); + } + break; + case DM_LINES_TRIP: + { + drawLine(points[0], points[1]); + for (size_t i = 2; i < count; i++) { + drawLine(points[i - 1], points[i]); + } + } + break; + }; +} + int Rester::size() { return _width * _height * sizeof (Rgba); } @@ -63,9 +201,9 @@ void Rester::clean() { } bool Rester::setPixel(int x, int y, Rgba color) { - if (x < 0 || y < 0 || x >= 500 || y >= 500) { + if (x < 0 || y < 0 || x >= _width || y >= _height) { return false; } //行列是反的 - buffer[y * _width + x] = color; + buffer[ (_height - y) * _width + x] = color; } \ No newline at end of file diff --git a/src/Rester.h b/src/Rester.h index 571f507..1e36132 100644 --- a/src/Rester.h +++ b/src/Rester.h @@ -14,12 +14,24 @@ #ifndef RESTER_H #define RESTER_H +#include "common.h" + +enum DRAWMODE { + DM_POINTS = 0, + DM_LINES = 1, + DM_LINES_LOOP = 2, + DM_LINES_TRIP = 3 +}; + class Rester { public: Rgba* buffer; Rester(int width, int height); virtual ~Rester(); - void drawPointer(int x, int y, Rgba color, int pointSize = 1); + void drawPoint(int x, int y, Rgba color = Rgba(255, 0, 0, 0), int pointSize = 1); + void drawLine(float2 p1, float2 p2, Rgba color = Rgba(255, 0, 0, 0)); + void drawLine(float2 p1, float2 p2, Rgba color1, Rgba color2); + void drawArray(DRAWMODE mode, const float2* points, size_t count); int size(); void clean(); bool setPixel(int x, int y, Rgba color); diff --git a/src/Rgba.h b/src/Rgba.h index 74fdd1f..62ee425 100644 --- a/src/Rgba.h +++ b/src/Rgba.h @@ -29,5 +29,16 @@ public: unsigned char _a; }; +inline Rgba colorLerp(const Rgba& color1, const Rgba& color2, float step) { + Rgba ret; + + ret._r = (unsigned char) color1._r + step * (color2._r - color1._r); + ret._g = (unsigned char) color1._g + step * (color2._g - color1._g); + ret._b = (unsigned char) color1._b + step * (color2._b - color1._b); + ret._a = (unsigned char) color1._a + step * (color2._a - color1._a); + + return ret; +} + #endif /* RGBA_H */ diff --git a/src/common.h b/src/common.h index 37808f3..79033a3 100644 --- a/src/common.h +++ b/src/common.h @@ -14,16 +14,48 @@ #ifndef COMMON_H #define COMMON_H -#ifdef __cplusplus -extern "C" { -#endif +#include +#include #define die(m) do { perror(m); exit(EXIT_FAILURE); } while(0) +#define def2rad(theta) (0.01745329251994329 * (theta)) //每个角度所对应的弧度 +template +struct tvec2 { + typedef T value_type; + typedef std::size_t size_type; + typedef tvec2 type; -#ifdef __cplusplus -} -#endif + value_type x; + value_type y; + + size_type length() const { + return 2; + } + + value_type operator[](size_type i) { + assert(i < this->length()); + return (&x)[i]; + } + + tvec2() { + x = 0; + y = 0; + } + + tvec2(const value_type &s) { + x = s; + y = s; + } + + tvec2(const value_type &s1, const value_type &s2) { + x = s1; + y = s2; + } +}; + + +typedef tvec2 float2; #endif /* COMMON_H */ diff --git a/src/gtktest.cc b/src/gtktest.cc index 42c29c8..25244f5 100644 --- a/src/gtktest.cc +++ b/src/gtktest.cc @@ -1,4 +1,5 @@ #include +#include #include #include #include "Rgba.h" @@ -23,13 +24,36 @@ unsigned char* makeBitmapRand() { unsigned char* makeBitmap() { rester.clean(); - unsigned char* data = new unsigned char[width * height * 4]; + for (int i = 0; i < 100; i++) { - rester.drawPointer(rand() % 500, rand() % 500, Rgba(255, 0, 0), 3); + rester.drawPoint(rand() % height, rand() % width, Rgba(255, 0, 0), 3); } - memcpy(data, rester.buffer, rester.size()); - return data; + rester.drawLine(float2(100, 100), float2(100, 222), Rgba(255, 0, 0)); + rester.drawLine(float2(100, 100), float2(400, 400), Rgba(255, 0, 0), Rgba(0, 255, 0)); + + + float2 arrPoints[] = { + float2(11, 34), + float2(33, 66), + float2(1, 100), + float2(22, 88), + float2(100, 1) + }; + + rester.drawArray(DM_LINES_TRIP, arrPoints, sizeof (arrPoints) / sizeof (arrPoints[0])); + + float2 center(250, 250); + float radius = 80; + float2 arrCircle[360]; + + for (int i = 0; i < 180; i++) { + arrCircle[i].x = radius * cos(def2rad(i)) + center.x; + arrCircle[i].y = radius * sin(def2rad(i)) + center.y; + } + rester.drawArray(DM_LINES_TRIP, arrCircle, sizeof (arrCircle) / sizeof (arrCircle[0])); + + return (unsigned char*) rester.buffer; } void render(GtkWidget *widget) { @@ -51,7 +75,7 @@ void render(GtkWidget *widget) { g_object_unref(pixbuf); g_object_unref(pixmap); - delete data; + //delete data; } int main(int argc, char* argv[]) { diff --git a/src/tt.cc b/src/tt.cc index 15c0fed..39caeff 100644 --- a/src/tt.cc +++ b/src/tt.cc @@ -3,21 +3,36 @@ #include #include #include +#include "common.h" using namespace std; +struct Ms { + int x; + int y; + + int operator[](int i) { + return (&x)[i]; + } +}; + int main() { - Rgba x(255, 0, 0, 255); - Rgba y(0, 0, 255, 255); + /*tvec2 x(2, 6); + cout << x[0] << endl;*/ - unsigned char* z = new unsigned char[4]; - - Rgba buffer[5][5]; + /*int y = 67305985; + + bitset<32> set = y; + cout << set << endl; + + unsigned char* p; + + p = (unsigned char*) &y; + + cout << (int) p[3] << endl;*/ + + + float2 x(2.0, 1.2); - printf("%ld\n", sizeof(buffer)); - //memcpy(z, x, sizeof(x)); -// -// -// bitset<32> set = (int)z; -// cout << set << endl; + cout << x[0] << endl; }