Tscope5
primitives.c
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // __ ______
4 // / /_______________ ____ ___ / ____/
5 // / __/ ___/ ___/ __ \/ __ \/ _ \ /___ )
6 // / /_(__ ) /__/ /_/ / /_/ / __/ ____/ /
7 // \__/____/\___/\____/ .___/\___/ /_____/
8 // /_/
9 //
10 /// \file primitives.c
11 /// Definitions of primitives drawing functions.
12 /// \example primitives01.c
13 /// \example primitives02.c
14 /// \example primitives03.c
15 /// \example primitives04.c
16 ////////////////////////////////////////////////////////////////////////////////
17 
18 
19 #include "../include/tscope5/primitives.h"
20 #include "../include/tscope5/graphics.h"
21 #include "../include/tscope5/primitives_internal.h"
22 #include "../include/tscope5/system_internal.h"
23 #include "../include/tscope5/graphics_internal.h"
24 
25 #include <allegro5/allegro_primitives.h>
26 
27 
28 ////////////////////////////////////////////////////////////////////////////////
29 /// @name Primitives drawing functions
30 /// The drawing functions all take the smallest possible number of parameters
31 /// to put something on the screen: some coordinates.
32 /// Drawing parameters are set with the graphics parameter functions.
33 //@{
34 ////////////////////////////////////////////////////////////////////////////////
35 
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// Draw a pixel.
39 ///
40 /// \param x Horizontal position of the pixel.
41 /// \param y Vertical position of the pixel.
42 ////////////////////////////////////////////////////////////////////////////////
43 void ts5_draw_pixel(double x, double y)
44 {
45  ts5_check_primitives("ts5_draw_pixel");
46  ts5_log(TS5_LOGLEVEL_5, "ts5_draw_pixel(%f,%f)\n", x, y);
47 
48  if (_ts5_status.graphics.coordinate_scale
49  == TS5_RELATIVE_COORDINATES) {
52  }
53 
54  if (_ts5_status.graphics.coordinate_system
55  == TS5_CARTESIAN_COORDINATES) {
58  }
59 
60  x *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
61  y *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
62 
63  if (_ts5_status.graphics.drawing_thickness <= 0.0) {
64  al_draw_pixel(x, y, _ts5_status.graphics.foreground_color);
65  }
66  else {
67  al_draw_filled_circle(x, y,
68  _ts5_status.graphics.drawing_thickness *
69  _ts5_status.display[_ts5_status.active_display].sampling_factor,
70  _ts5_status.graphics.foreground_color);
71  }
72 }
73 
74 
75 ////////////////////////////////////////////////////////////////////////////////
76 /// Get the color of a pixel.
77 ///
78 /// \param x Horizontal position of the pixel.
79 /// \param y Vertical position of the pixel.
80 ///
81 /// Return value:
82 /// TS5_COLOR structure.
83 ////////////////////////////////////////////////////////////////////////////////
84 TS5_COLOR ts5_get_pixel_color(double x, double y)
85 {
86  ts5_check_primitives("ts5_get_pixel_color");
87  ts5_log(TS5_LOGLEVEL_5, "ts5_get_pixel_color(%f,%f)\n", x, y);
88 
89  if (_ts5_status.graphics.coordinate_scale
90  == TS5_RELATIVE_COORDINATES) {
93  }
94 
95  if (_ts5_status.graphics.coordinate_system
96  == TS5_CARTESIAN_COORDINATES) {
99  }
100 
101  x *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
102  y *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
103 
104  return (al_get_pixel(_ts5_data.target, x, y));
105 }
106 
107 
108 ////////////////////////////////////////////////////////////////////////////////
109 /// Draw a line segment.
110 ///
111 /// \param x1 Horizontal position of the start point of the line segment.
112 /// \param y1 Vertical position of the start point of the line segment.
113 /// \param x2 Horizontal position of the end point of the line segment.
114 /// \param y2 Vertical position of the end point of the line segment.
115 ////////////////////////////////////////////////////////////////////////////////
116 void ts5_draw_line(double x1, double y1, double x2, double y2)
117 {
118  ts5_check_primitives("ts5_draw_line");
119  ts5_log(TS5_LOGLEVEL_5, "ts5_draw_line(%f,%f,%f,%f)\n", x1, y1, x2, y2);
120 
121  if (_ts5_status.graphics.coordinate_scale
122  == TS5_RELATIVE_COORDINATES) {
127  }
128 
129  if (_ts5_status.graphics.coordinate_system
130  == TS5_CARTESIAN_COORDINATES) {
135  }
136 
137  x1 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
138  x2 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
139  y1 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
140  y2 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
141 
142  al_draw_line(x1, y1, x2, y2, _ts5_status.graphics.foreground_color,
143  _ts5_status.graphics.drawing_thickness *
144  _ts5_status.display[_ts5_status.active_display].sampling_factor);
145 }
146 
147 
148 ////////////////////////////////////////////////////////////////////////////////
149 /// Draw a rectangle.
150 ///
151 /// \param x1 Horizontal position of the first corner of the rectangle.
152 /// \param y1 Vertical position of the first corner of the rectangle.
153 /// \param x2 Horizontal position of the second corner of the rectangle.
154 /// \param y2 Vertical position of the second corner of the rectangle.
155 ////////////////////////////////////////////////////////////////////////////////
156 void ts5_draw_rectangle(double x1, double y1, double x2, double y2)
157 {
158  ts5_check_primitives("ts5_draw_rectangle");
159  ts5_log(TS5_LOGLEVEL_5, "ts5_draw_rectangle(%f,%f,%f,%f)\n",
160  x1, y1, x2, y2);
161 
162  if (_ts5_status.graphics.coordinate_scale
163  == TS5_RELATIVE_COORDINATES) {
168  }
169 
170  if (_ts5_status.graphics.coordinate_system
171  == TS5_CARTESIAN_COORDINATES) {
176  }
177 
178  x1 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
179  x2 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
180  y1 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
181  y2 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
182 
183  if (!_ts5_status.graphics.fill_mode) {
184  al_draw_rectangle(x1, y1, x2, y2,
185  _ts5_status.graphics.foreground_color,
186  _ts5_status.graphics.drawing_thickness *
187  _ts5_status.display[_ts5_status.active_display].sampling_factor);
188  }
189  else {
190  al_draw_filled_rectangle(x1, y1, x2, y2,
191  _ts5_status.graphics.foreground_color);
192  }
193 }
194 
195 
196 ////////////////////////////////////////////////////////////////////////////////
197 /// Draw a rounded rectangle.
198 ///
199 /// \param x1 Horizontal position of the first corner of the rectangle.
200 /// \param y1 Vertical position of the first corner of the rectangle.
201 /// \param x2 Horizontal position of the second corner of the rectangle.
202 /// \param y2 Vertical position of the second corner of the rectangle.
203 /// \param rx Horizontal radius of the round.
204 /// \param ry Vertical radius of the round.
205 ////////////////////////////////////////////////////////////////////////////////
206 void ts5_draw_rounded_rectangle(double x1, double y1, double x2, double y2,
207  double rx, double ry)
208 {
209  ts5_check_primitives("ts5_draw_rounded_rectangle");
210  ts5_log(TS5_LOGLEVEL_5, "ts5_draw_rounded_rectangle(%f,%f,%f,%f,%f,%f)\n",
211  x1, y1, x2, y2, rx, ry);
212 
213  if (_ts5_status.graphics.coordinate_scale
214  == TS5_RELATIVE_COORDINATES) {
221  }
222 
223  if (_ts5_status.graphics.coordinate_system
224  == TS5_CARTESIAN_COORDINATES) {
229  }
230 
231  if (x1 > x2) {
232  double t = x1;
233  x1 = x2;
234  x2 = t;
235  }
236 
237  if (y1 > y2) {
238  double t = y1;
239  y1 = y2;
240  y2 = t;
241  }
242 
243  double w = x2 - x1;
244 
245  if (rx>w/2.0) {
246  rx=w/2.0;
247  }
248 
249  double h = y2 - y1;
250 
251  if (ry>h/2.0) {
252  ry=h/2.0;
253  }
254 
255  x1 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
256  x2 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
257  y1 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
258  y2 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
259  rx *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
260  ry *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
261 
262  if (!_ts5_status.graphics.fill_mode) {
263  al_draw_rounded_rectangle(x1, y1, x2, y2, rx, ry,
264  _ts5_status.graphics.foreground_color,
265  _ts5_status.graphics.drawing_thickness *
266  _ts5_status.display[_ts5_status.active_display].sampling_factor);
267  }
268  else {
269  al_draw_filled_rounded_rectangle(x1, y1, x2, y2, rx, ry,
270  _ts5_status.graphics.foreground_color);
271  }
272 }
273 
274 
275 ////////////////////////////////////////////////////////////////////////////////
276 /// Draw a triangle.
277 ///
278 /// \param x1 Horizontal position of the first corner of the triangle.
279 /// \param y1 Vertical position of the first corner of the triangle.
280 /// \param x2 Horizontal position of the second corner of the triangle.
281 /// \param y2 Vertical position of the second corner of the triangle.
282 /// \param x3 Horizontal position of the third corner of the triangle.
283 /// \param y3 Vertical position of the third corner of the triangle.
284 ////////////////////////////////////////////////////////////////////////////////
285 void ts5_draw_triangle(double x1, double y1, double x2, double y2,
286  double x3, double y3)
287 {
288  ts5_check_primitives("ts5_draw_triangle");
289  ts5_log(TS5_LOGLEVEL_5, "ts5_draw_triangle(%f,%f,%f,%f,%f,%f)\n",
290  x1, y1, x2, y2, x3, y3);
291 
292  if (_ts5_status.graphics.coordinate_scale
293  == TS5_RELATIVE_COORDINATES) {
300  }
301 
302  if (_ts5_status.graphics.coordinate_system
303  == TS5_CARTESIAN_COORDINATES) {
310  }
311 
312  x1 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
313  x2 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
314  x3 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
315  y1 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
316  y2 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
317  y3 *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
318 
319  if (!_ts5_status.graphics.fill_mode) {
320  al_draw_triangle(x1, y1, x2, y2, x3, y3,
321  _ts5_status.graphics.foreground_color,
322  _ts5_status.graphics.drawing_thickness *
323  _ts5_status.display[_ts5_status.active_display].sampling_factor);
324  }
325  else {
326  al_draw_filled_triangle(x1, y1, x2, y2, x3, y3,
327  _ts5_status.graphics.foreground_color);
328  }
329 }
330 
331 
332 ////////////////////////////////////////////////////////////////////////////////
333 /// Draw a circle.
334 ///
335 /// \param cx Horizontal position of the center of the circle.
336 /// \param cy Vertical position of the center of the circle.
337 /// \param r Radius of the circle.
338 ////////////////////////////////////////////////////////////////////////////////
339 void ts5_draw_circle(double cx, double cy, double r)
340 {
341  ts5_check_primitives("ts5_draw_circle");
342  ts5_log(TS5_LOGLEVEL_5, "ts5_draw_circle(%f,%f,%f)\n", cx, cy, r);
343 
344  if (_ts5_status.graphics.coordinate_scale
345  == TS5_RELATIVE_COORDINATES) {
349  }
350 
351  if (_ts5_status.graphics.coordinate_system
352  == TS5_CARTESIAN_COORDINATES) {
355  }
356 
357  cx *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
358  cy *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
359  r *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
360 
361  if (!_ts5_status.graphics.fill_mode) {
362  al_draw_circle(cx, cy, r, _ts5_status.graphics.foreground_color,
363  _ts5_status.graphics.drawing_thickness *
364  _ts5_status.display[_ts5_status.active_display].sampling_factor);
365  }
366  else {
367  al_draw_filled_circle(cx, cy, r,
368  _ts5_status.graphics.foreground_color);
369  }
370 }
371 
372 
373 ////////////////////////////////////////////////////////////////////////////////
374 /// Draw an ellipse.
375 ///
376 /// \param cx Horizontal position of the center of the ellipse.
377 /// \param cy Vertical position of the center of the ellipse.
378 /// \param rx Horizontal radius of the ellipse.
379 /// \param ry Vertical radius of the ellipse.
380 ////////////////////////////////////////////////////////////////////////////////
381 void ts5_draw_ellipse(double cx, double cy, double rx, double ry)
382 {
383  ts5_check_primitives("ts5_draw_ellipse");
384  ts5_log(TS5_LOGLEVEL_5, "ts5_draw_ellipse(%f,%f,%f,%f)\n", cx, cy, rx, ry);
385 
386  if (_ts5_status.graphics.coordinate_scale
387  == TS5_RELATIVE_COORDINATES) {
392  }
393 
394  if (_ts5_status.graphics.coordinate_system
395  == TS5_CARTESIAN_COORDINATES) {
398  }
399 
400  cx *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
401  cy *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
402  rx *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
403  ry *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
404 
405  if (!_ts5_status.graphics.fill_mode) {
406  al_draw_ellipse(cx, cy, rx, ry,
407  _ts5_status.graphics.foreground_color,
408  _ts5_status.graphics.drawing_thickness *
409  _ts5_status.display[_ts5_status.active_display].sampling_factor);
410  }
411  else {
412  al_draw_filled_ellipse(cx, cy, rx, ry,
413  _ts5_status.graphics.foreground_color);
414  }
415 }
416 
417 
418 ////////////////////////////////////////////////////////////////////////////////
419 /// Draw an arc.
420 ///
421 /// \param cx Horizontal position of the center of the arc.
422 /// \param cy Vertical position of the center of the arc.
423 /// \param r Radius of the arc.
424 /// \param start The initial angle of the arc (0.0 = west, 90.0 = north, ...).
425 /// \param delta Span of the arc (positive is counter clockwise,
426 /// negative is clockwise).
427 ////////////////////////////////////////////////////////////////////////////////
428 void ts5_draw_arc(double cx, double cy, double r, double start, double delta)
429 {
430  ts5_check_primitives("ts5_draw_arc");
431  ts5_log(TS5_LOGLEVEL_5, "ts5_draw_arc(%f,%f,%f,%f,%f)\n",
432  cx, cy, r, start, delta);
433 
434  if (_ts5_status.graphics.coordinate_scale
435  == TS5_RELATIVE_COORDINATES) {
439  }
440 
441  if (_ts5_status.graphics.coordinate_system
442  == TS5_CARTESIAN_COORDINATES) {
445  }
446 
447  cx *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
448  cy *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
449  r *= _ts5_status.display[_ts5_status.active_display].sampling_factor;
450 
451  start = - start * TS5_PI / 180;
452  delta = - delta * TS5_PI / 180;
453  al_draw_arc(cx, cy, r, start, delta,
454  _ts5_status.graphics.foreground_color,
455  _ts5_status.graphics.drawing_thickness *
456  _ts5_status.display[_ts5_status.active_display].sampling_factor);
457 }
458 
459 
460 ////////////////////////////////////////////////////////////////////////////////
461 //@}
462 ////////////////////////////////////////////////////////////////////////////////
void ts5_draw_pixel(double x, double y)
Draw a pixel.
Definition: primitives.c:43
void ts5_draw_rectangle(double x1, double y1, double x2, double y2)
Draw a rectangle.
Definition: primitives.c:156
void ts5_check_primitives(char *calling_function)
Do some checks at the start of each primitives function.
void ts5_draw_rounded_rectangle(double x1, double y1, double x2, double y2, double rx, double ry)
Draw a rounded rectangle.
Definition: primitives.c:206
double ts5_relative_to_absolute_coordinate_x(const double x)
Convert a relative horizontal coordinate into an absolute horizontal coordinate.
Definition: graphics.c:208
void ts5_draw_ellipse(double cx, double cy, double rx, double ry)
Draw an ellipse.
Definition: primitives.c:381
TS5_COLOR ts5_get_pixel_color(double x, double y)
Get the color of a pixel.
Definition: primitives.c:84
void ts5_draw_circle(double cx, double cy, double r)
Draw a circle.
Definition: primitives.c:339
void ts5_log(const unsigned int level, const char *format,...)
Send info to a logging window.
Definition: system.c:45
double ts5_cartesian_to_display_coordinate_x(const double x)
Convert a horizontal Cartesian coordinate into a horizontal display coordinate.
Definition: graphics.c:333
double ts5_cartesian_to_display_coordinate_y(const double y)
Convert a vertical Cartesian coordinate into a vertical display coordinate.
Definition: graphics.c:354
void ts5_draw_arc(double cx, double cy, double r, double start, double delta)
Draw an arc.
Definition: primitives.c:428
void ts5_draw_triangle(double x1, double y1, double x2, double y2, double x3, double y3)
Draw a triangle.
Definition: primitives.c:285
void ts5_draw_line(double x1, double y1, double x2, double y2)
Draw a line segment.
Definition: primitives.c:116
double ts5_relative_to_absolute_coordinate_y(const double y)
Convert a relative vertical coordinate into an absolute vertical coordinate.
Definition: graphics.c:240