आवश्यकताओं को देखते हुए यह लग रहा है वहाँ एक सरल उपाय है जैसे।
सबसे पहले, त्रिभुज किनारों को रास्टराइज करें। आप उस के लिए ब्रेसनहेम लाइन ड्रॉइंग एल्गोरिदम का उपयोग कर सकते हैं (जैसा कि नीचे दिए गए कोड में है) या जो कुछ भी काम करता है। फिर बीच में क्षेत्र भरें। यह मनमाने ढंग से पतले त्रिकोण के साथ काम करेगा।
यह सुनिश्चित करने के लिए कि त्रिभुजों को खींचा जाने वाले क्रम के बावजूद कोई अंतराल नहीं है और त्रिभुज-ड्राइंग कोड को प्रदान किए गए शिखर के क्रम के बावजूद आप साझा किनारों को समान रूप से साझा करने वाले त्रिकोणों में रास्टराइज़ करना चाहते हैं धार। वही तरीका हर बार एक ही पिक्सल का मतलब है।
यह सुनिश्चित करने के लिए कि हर बार जब आप वर्टेक्स निर्देशांक के समान जोड़े से एक ही पिक्सल प्राप्त करते हैं, तो आप मूल रूप से एक निश्चित क्रम स्थापित करना चाहते हैं, यानी एक ऐसा नियम स्थापित करें जो हमेशा दिए गए दो में से एक ही वर्टेक्स का चयन करेगा जिस क्रम में उन्हें दिया जाता है।
इस आदेश को लागू करने का एक आसान तरीका है आपकी लाइन (त्रिकोण किनारे) को 2-डी वेक्टर के रूप में पेश करना और इसकी दिशा को फ़्लिप करना यदि यह नकारात्मक वाई की दिशा में इंगित करता है या एक्स अक्ष के समानांतर होता है और इसमें अंक नकारात्मक एक्स की दिशा। कुछ ASCII कला के लिए समय! :)
3 2 1
\ |/
\ |/
\|/
4 --------+--------- 0
/|\
/| \
/| \
5 6 7
4 -> 0
5 -> 1
6 -> 2
7 -> 3
देखें, यहाँ रेखा खंड, कहते हैं, 1 और रेखा खंड 5 वास्तव में बात यह है कि एक ही प्रकार हैं, फर्क सिर्फ इतना है अन्य समाप्ति बिंदु को मूल में अंत बिंदु से दिशा है। इसलिए हम इन मामलों को आधे से घटाकर 4 से 7 खंडों को 0 से 3 तक विभाजित करके दिशा निर्देश अस्पष्टता से छुटकारा पा सकते हैं। आइओ, हम बढ़ते एक्स की दिशा में, किनारे पर समान हैं, या तो वाई के OR को बढ़ाने की दिशा में जाना चुनते हैं।
#include <stddef.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define SCREEN_HEIGHT 22
#define SCREEN_WIDTH 78
// Simulated frame buffer
char Screen[SCREEN_HEIGHT][SCREEN_WIDTH];
void SetPixel(long x, long y, char color)
{
if ((x < 0) || (x >= SCREEN_WIDTH) ||
(y < 0) || (y >= SCREEN_HEIGHT))
{
return;
}
if (Screen[y][x] == ' ')
Screen[y][x] = color;
else
Screen[y][x] = '*';
}
void Visualize(void)
{
long x, y;
for (y = 0; y < SCREEN_HEIGHT; y++)
{
for (x = 0; x < SCREEN_WIDTH; x++)
{
printf("%c", Screen[y][x]);
}
printf("\n");
}
}
typedef struct
{
long x, y;
unsigned char color;
} Point2D;
// min X and max X for every horizontal line within the triangle
long ContourX[SCREEN_HEIGHT][2];
#define ABS(x) ((x >= 0) ? x : -x)
// Scans a side of a triangle setting min X and max X in ContourX[][]
// (using the Bresenham's line drawing algorithm).
void ScanLine(long x1, long y1, long x2, long y2)
{
long sx, sy, dx1, dy1, dx2, dy2, x, y, m, n, k, cnt;
sx = x2 - x1;
sy = y2 - y1;
/*
3 2 1
\ |/
\ |/
\|/
4 --------+--------- 0
/|\
/| \
/| \
5 6 7
4 -> 0
5 -> 1
6 -> 2
7 -> 3
*/
if (sy < 0 || sy == 0 && sx < 0)
{
k = x1; x1 = x2; x2 = k;
k = y1; y1 = y2; y2 = k;
sx = -sx;
sy = -sy;
}
if (sx > 0) dx1 = 1;
else if (sx < 0) dx1 = -1;
else dx1 = 0;
if (sy > 0) dy1 = 1;
else if (sy < 0) dy1 = -1;
else dy1 = 0;
m = ABS(sx);
n = ABS(sy);
dx2 = dx1;
dy2 = 0;
if (m < n)
{
m = ABS(sy);
n = ABS(sx);
dx2 = 0;
dy2 = dy1;
}
x = x1; y = y1;
cnt = m + 1;
k = n/2;
while (cnt--)
{
if ((y >= 0) && (y < SCREEN_HEIGHT))
{
if (x < ContourX[y][0]) ContourX[y][0] = x;
if (x > ContourX[y][1]) ContourX[y][1] = x;
}
k += n;
if (k < m)
{
x += dx2;
y += dy2;
}
else
{
k -= m;
x += dx1;
y += dy1;
}
}
}
void DrawTriangle(Point2D p0, Point2D p1, Point2D p2)
{
long y;
for (y = 0; y < SCREEN_HEIGHT; y++)
{
ContourX[y][0] = LONG_MAX; // min X
ContourX[y][1] = LONG_MIN; // max X
}
ScanLine(p0.x, p0.y, p1.x, p1.y);
ScanLine(p1.x, p1.y, p2.x, p2.y);
ScanLine(p2.x, p2.y, p0.x, p0.y);
for (y = 0; y < SCREEN_HEIGHT; y++)
{
if (ContourX[y][1] >= ContourX[y][0])
{
long x = ContourX[y][0];
long len = 1 + ContourX[y][1] - ContourX[y][0];
// Can draw a horizontal line instead of individual pixels here
while (len--)
{
SetPixel(x++, y, p0.color);
}
}
}
}
int main(void)
{
Point2D p0, p1, p2, p3;
// clear the screen
memset(Screen, ' ', sizeof(Screen));
// generate random triangle coordinates
srand((unsigned)time(NULL));
// p0 - p1 is going to be the shared edge,
// make sure the triangles don't intersect
for (;;)
{
p0.x = rand() % SCREEN_WIDTH;
p0.y = rand() % SCREEN_HEIGHT;
p1.x = rand() % SCREEN_WIDTH;
p1.y = rand() % SCREEN_HEIGHT;
p2.x = rand() % SCREEN_WIDTH;
p2.y = rand() % SCREEN_HEIGHT;
p3.x = rand() % SCREEN_WIDTH;
p3.y = rand() % SCREEN_HEIGHT;
{
long vsx = p0.x - p1.x;
long vsy = p0.y - p1.y;
long v1x = p0.x - p2.x;
long v1y = p0.y - p2.y;
long v2x = p0.x - p3.x;
long v2y = p0.y - p3.y;
long z1 = vsx * v1y - v1x * vsy;
long z2 = vsx * v2y - v2x * vsy;
// break if p2 and p3 are on the opposite sides of p0-p1
if (z1 * z2 < 0) break;
}
}
printf("%ld:%ld %ld:%ld %ld:%ld %ld:%ld\n\n",
p0.x, p0.y,
p1.x, p1.y,
p2.x, p2.y,
p3.x, p3.y);
// draw the triangles
p0.color = '-';
DrawTriangle(p0, p3, p1);
p1.color = '+';
DrawTriangle(p1, p2, p0);
Visualize();
return 0;
}
नमूना उत्पादन:
30:10 5:16 16:6 59:17
+++
++++++++
++++++++++++
+++++++++++++++++
+++++++++++++++****---
+++++++++++++****-----------
++++++++++****-------------------
++++++*****----------------------------
+++****-------------------------------------
****---------------------------------------------
*-----------------------------------------------------
-
लीजेंड:
यहाँ कैसे आप कोड में यह कर सकता है
- "+" - त्रिकोण 1
- के पिक्सल " - "- त्रिभुज के पिक्सेल 2
- "*" - बढ़त के पिक्सल (वजह से त्रिकोण 1 और 2
खबरदार है कि भले ही कोई रिक्त अंतराल (पिक्सेल), त्रिकोण जिसका पिक्सल (साझा किनारे पर) अधिलेखित हो हो जाएगा के बीच साझा किया इसके शीर्ष पर खींचा गया दूसरा त्रिकोण) बहुत पतला होने पर अलग या अजीब रूप से आकार के रूप में दिखाई दे सकता है। उदाहरण:
2:20 12:8 59:15 4:17
*++++++
*+++++++++++++
*+++++++++++++++++++++
-*++++++++++++++++++++++++++++
-*++++++++++++++++++++++++++++++++++++
*+++++++++++++++++++++++++++++++++++++++++++
*+++++++++++++++++++++++++++++++++++++++++++++++++++
*+++++++++++++++++++++++++++++++++++++++++++++++++++++
*+++++++++++++++++++++++++++++++++++++++++++
-*+++++++++++++++++++++++++++++++
-*+++++++++++++++++++++
*++++++++++
*
आप बस (अपने पुस्तकालय की) एक डिफ़ॉल्ट भरने प्रक्रिया के साथ त्रिकोण नहीं बना सकता है और फिर से एक भी पोस्ट-प्रोसेसिंग आपरेशन लापता पिक्सल भरता है? – emesx
@ एल्म्स: यह एक स्वीकार्य दृष्टिकोण होगा, लेकिन यह अभी भी गायब पिक्सल की पहचान के लिए 'अच्छा एल्गोरिदम' छोड़ देता है। (मुझे आशा है कि जो कोई मुझे ग्राफिक्स के बारे में और जानता है, वह मुझे त्रिभुज-रास्टरराइजेशन एल्गोरिदम जानता है जो इसे पहले स्थान पर होने से रोकता है।) – Tynam
ठीक है, क्या आप पृष्ठभूमि का रंग जानते हैं? यहां तक कि यदि आप नहीं करते हैं, तो आप एक सरल ईरोड/पोस्ट प्रोसेसिंग को फैलाने का प्रयास कर सकते हैं। – emesx