source: libcaca/trunk/caca/triangle.c @ 2821

Last change on this file since 2821 was 2821, checked in by Sam Hocevar, 11 years ago

Starting refactoring to get rid of libcucul. The initial reason for the
split is rendered moot by the plugin system: when enabled, binaries do
not link directly with libX11 or libGL. I hope this is a step towards
more consisteny and clarity.

  • Property svn:keywords set to Id
File size: 4.5 KB
Line 
1/*
2 *  libcaca       Colour ASCII-Art library
3 *  Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: triangle.c 2821 2008-09-27 13:12:46Z sam $
7 *
8 *  This library is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15/*
16 *  This file contains triangle drawing functions, both filled and outline.
17 */
18
19#include "config.h"
20
21#if !defined(__KERNEL__)
22#   include <stdlib.h>
23#endif
24
25#include "caca.h"
26#include "caca_internals.h"
27
28/** \brief Draw a triangle on the canvas using the given character.
29 *
30 *  This function never fails.
31 *
32 *  \param cv The handle to the libcaca canvas.
33 *  \param x1 X coordinate of the first point.
34 *  \param y1 Y coordinate of the first point.
35 *  \param x2 X coordinate of the second point.
36 *  \param y2 Y coordinate of the second point.
37 *  \param x3 X coordinate of the third point.
38 *  \param y3 Y coordinate of the third point.
39 *  \param ch UTF-32 character to be used to draw the triangle outline.
40 *  \return This function always returns 0.
41 */
42int caca_draw_triangle(caca_canvas_t *cv, int x1, int y1, int x2, int y2,
43                        int x3, int y3, uint32_t ch)
44{
45    caca_draw_line(cv, x1, y1, x2, y2, ch);
46    caca_draw_line(cv, x2, y2, x3, y3, ch);
47    caca_draw_line(cv, x3, y3, x1, y1, ch);
48
49    return 0;
50}
51
52/** \brief Draw a thin triangle on the canvas.
53 *
54 *  This function never fails.
55 *
56 *  \param cv The handle to the libcaca canvas.
57 *  \param x1 X coordinate of the first point.
58 *  \param y1 Y coordinate of the first point.
59 *  \param x2 X coordinate of the second point.
60 *  \param y2 Y coordinate of the second point.
61 *  \param x3 X coordinate of the third point.
62 *  \param y3 Y coordinate of the third point.
63 *  \return This function always returns 0.
64 */
65int caca_draw_thin_triangle(caca_canvas_t *cv, int x1, int y1,
66                             int x2, int y2, int x3, int y3)
67{
68    caca_draw_thin_line(cv, x1, y1, x2, y2);
69    caca_draw_thin_line(cv, x2, y2, x3, y3);
70    caca_draw_thin_line(cv, x3, y3, x1, y1);
71
72    return 0;
73}
74
75/** \brief Fill a triangle on the canvas using the given character.
76 *
77 *  This function never fails.
78 *
79 *  \param cv The handle to the libcaca canvas.
80 *  \param x1 X coordinate of the first point.
81 *  \param y1 Y coordinate of the first point.
82 *  \param x2 X coordinate of the second point.
83 *  \param y2 Y coordinate of the second point.
84 *  \param x3 X coordinate of the third point.
85 *  \param y3 Y coordinate of the third point.
86 *  \param ch UTF-32 character to be used to fill the triangle.
87 *  \return This function always returns 0.
88 */
89int caca_fill_triangle(caca_canvas_t *cv, int x1, int y1, int x2, int y2,
90                        int x3, int y3, uint32_t ch)
91{
92    int x, y, xmin, xmax, ymin, ymax;
93    int xx1, xx2, xa, xb, sl21, sl31, sl32;
94
95    /* Bubble-sort y1 <= y2 <= y3 */
96    if(y1 > y2)
97        return caca_fill_triangle(cv, x2, y2, x1, y1, x3, y3, ch);
98
99    if(y2 > y3)
100        return caca_fill_triangle(cv, x1, y1, x3, y3, x2, y2, ch);
101
102    /* Compute slopes and promote precision */
103    sl21 = (y2 == y1) ? 0 : (x2 - x1) * 0x10000 / (y2 - y1);
104    sl31 = (y3 == y1) ? 0 : (x3 - x1) * 0x10000 / (y3 - y1);
105    sl32 = (y3 == y2) ? 0 : (x3 - x2) * 0x10000 / (y3 - y2);
106
107    x1 *= 0x10000;
108    x2 *= 0x10000;
109    x3 *= 0x10000;
110
111    ymin = y1 < 0 ? 0 : y1;
112    ymax = y3 + 1 < cv->height ? y3 + 1 : cv->height;
113
114    if(ymin < y2)
115    {
116        xa = x1 + sl21 * (ymin - y1);
117        xb = x1 + sl31 * (ymin - y1);
118    }
119    else if(ymin == y2)
120    {
121        xa = x2;
122        xb = (y1 == y3) ? x3 : x1 + sl31 * (ymin - y1);
123    }
124    else /* (ymin > y2) */
125    {
126        xa = x3 + sl32 * (ymin - y3);
127        xb = x3 + sl31 * (ymin - y3);
128    }
129
130    /* Rasterize our triangle */
131    for(y = ymin; y < ymax; y++)
132    {
133        /* Rescale xa and xb, recentering the division */
134        if(xa < xb)
135        {
136            xx1 = (xa + 0x800) / 0x10000;
137            xx2 = (xb + 0x801) / 0x10000;
138        }
139        else
140        {
141            xx1 = (xb + 0x800) / 0x10000;
142            xx2 = (xa + 0x801) / 0x10000;
143        }
144
145        xmin = xx1 < 0 ? 0 : xx1;
146        xmax = xx2 + 1 < cv->width ? xx2 + 1 : cv->width;
147
148        for(x = xmin; x < xmax; x++)
149            caca_put_char(cv, x, y, ch);
150
151        xa += y < y2 ? sl21 : sl32;
152        xb += sl31;
153    }
154
155    return 0;
156}
157
Note: See TracBrowser for help on using the repository browser.