WIP Centered trochoids tools
Epitrochoid & Hypotrochoid to draw Spiralgraph / Wondergraph style line artwork. See https://sourceforge.net/p/tuxpaint/feature-requests/248/
This commit is contained in:
parent
cecb344faf
commit
6b4e82c8b4
2 changed files with 513 additions and 1 deletions
|
|
@ -6,7 +6,7 @@ Copyright (c) 2002-2024
|
|||
Various contributors (see below, and AUTHORS.txt)
|
||||
https://tuxpaint.org/
|
||||
|
||||
2024.January.2 (0.9.32)
|
||||
2024.January.7 (0.9.32)
|
||||
* Improvements to Magic tools:
|
||||
----------------------------
|
||||
* Support for complexity levels in Magic tools via the plugin API.
|
||||
|
|
@ -54,6 +54,19 @@ https://tuxpaint.org/
|
|||
(https://freesound.org/people/mudflea2/sounds/708182/)
|
||||
Creative Commons 0 by mudflea2
|
||||
|
||||
* WIP - Epitrochoid and Hypotrochoid magic tools:
|
||||
+ Tools to draw centered trochoids; to create art similar to a
|
||||
Spirograph or Wondergraph. Drag left/right to adjust the
|
||||
radius of the stator (fixed circle). Drag up/down to adjust
|
||||
radius of the rotator (the rolling circle). Size option
|
||||
adjusts the position of the virtual pen within the rotator.
|
||||
+ If "--nomagicsizes" is set, three versions each of
|
||||
epitrochoid and hypotrochoid drawing tools will be made
|
||||
available, each with differing pen positions.
|
||||
+ Code: Bill Kendrick <bill@newbreedsoftware.com>
|
||||
+ WIP - Needs icons
|
||||
+ WIP - Needs sounds
|
||||
|
||||
* Improvements to "Text" & "Label" tools:
|
||||
---------------------------------------
|
||||
* The name and size of the chosen font is shown in the instructions
|
||||
|
|
|
|||
499
magic/src/trochoids.c
Normal file
499
magic/src/trochoids.c
Normal file
|
|
@ -0,0 +1,499 @@
|
|||
/* trochoids.c
|
||||
|
||||
Magic tools to draw various centered trochoids;
|
||||
similar to art generated by devices like the
|
||||
Spirograph and Wondergraph.
|
||||
|
||||
by Bill Kendrick <bill@newbreedsoftware.com>
|
||||
|
||||
January 6, 2024 - January 7, 2024
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <libintl.h>
|
||||
|
||||
#include "tp_magic_api.h"
|
||||
#include "SDL_image.h"
|
||||
#include "SDL_mixer.h"
|
||||
|
||||
#define deg_cos(x) cos((float) (x) * M_PI / 180.0)
|
||||
#define deg_sin(x) sin((float) (x) * M_PI / 180.0)
|
||||
|
||||
/* All _possible_ tools */
|
||||
enum
|
||||
{
|
||||
TOOL_EPITROCHOID_SIZES,
|
||||
TOOL_EPITROCHOID_NOSIZES_1,
|
||||
TOOL_EPITROCHOID_NOSIZES_2,
|
||||
TOOL_EPITROCHOID_NOSIZES_3,
|
||||
TOOL_HYPOTROCHOID_SIZES,
|
||||
TOOL_HYPOTROCHOID_NOSIZES_1,
|
||||
TOOL_HYPOTROCHOID_NOSIZES_2,
|
||||
TOOL_HYPOTROCHOID_NOSIZES_3,
|
||||
NUM_TOOLS
|
||||
};
|
||||
|
||||
Uint8 tp_offers_sizes = 1;
|
||||
|
||||
int num_tools[2] = {
|
||||
6, /* when sizes not available */
|
||||
2, /* when sizes available */
|
||||
};
|
||||
|
||||
int * which_to_tool;
|
||||
|
||||
int which_to_tool_per_size_availability[2][6] = {
|
||||
/* when sizes not available */
|
||||
{
|
||||
TOOL_EPITROCHOID_NOSIZES_1,
|
||||
TOOL_EPITROCHOID_NOSIZES_2,
|
||||
TOOL_EPITROCHOID_NOSIZES_3,
|
||||
TOOL_HYPOTROCHOID_NOSIZES_1,
|
||||
TOOL_HYPOTROCHOID_NOSIZES_2,
|
||||
TOOL_HYPOTROCHOID_NOSIZES_3,
|
||||
},
|
||||
/* when sizes available */
|
||||
{
|
||||
TOOL_EPITROCHOID_SIZES,
|
||||
TOOL_HYPOTROCHOID_SIZES,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
},
|
||||
};
|
||||
|
||||
#define SIZE_WELLINSIDE 0.33
|
||||
#define SIZE_INSIDE 0.66
|
||||
#define SIZE_EDGE 1.00
|
||||
#define SIZE_OUTSIDE 1.50
|
||||
#define SIZE_WELLOUTSIDE 2.00
|
||||
#define NUM_SIZES 5
|
||||
|
||||
float trochoids_sizes_per_size_setting[NUM_SIZES] = {
|
||||
SIZE_WELLINSIDE,
|
||||
SIZE_INSIDE,
|
||||
SIZE_EDGE,
|
||||
SIZE_OUTSIDE,
|
||||
SIZE_WELLOUTSIDE,
|
||||
};
|
||||
/* Default to "SIZE_EDGE" */
|
||||
#define DEFAULT_SIZE 3
|
||||
|
||||
float trochoids_sizes_per_tool[NUM_TOOLS] = {
|
||||
0, // N/A; size controls available
|
||||
SIZE_INSIDE,
|
||||
SIZE_EDGE,
|
||||
SIZE_WELLOUTSIDE,
|
||||
0, // N/A; size controls available
|
||||
SIZE_INSIDE,
|
||||
SIZE_EDGE,
|
||||
SIZE_WELLOUTSIDE,
|
||||
};
|
||||
|
||||
const char *icon_filenames[NUM_TOOLS] = {
|
||||
"1pt_persp_select.png", /* FIXME */
|
||||
"1pt_persp_select.png", /* FIXME */
|
||||
"1pt_persp_select.png", /* FIXME */
|
||||
"1pt_persp_select.png", /* FIXME */
|
||||
"1pt_persp_select.png", /* FIXME */
|
||||
"1pt_persp_select.png", /* FIXME */
|
||||
"1pt_persp_select.png", /* FIXME */
|
||||
"1pt_persp_select.png", /* FIXME */
|
||||
};
|
||||
|
||||
|
||||
const char *tool_names[NUM_TOOLS] = {
|
||||
gettext_noop("Epitrochoid"),
|
||||
gettext_noop("Epitrochoid 1"),
|
||||
gettext_noop("Epitrochoid 2"),
|
||||
gettext_noop("Epitrochoid 3"),
|
||||
gettext_noop("Hypotrochoid"),
|
||||
gettext_noop("Hypotrochoid 1"),
|
||||
gettext_noop("Hypotrochoid 2"),
|
||||
gettext_noop("Hypotrochoid 3"),
|
||||
};
|
||||
|
||||
|
||||
const char *tool_descriptions[NUM_TOOLS] = {
|
||||
/* Epitrochoids */
|
||||
gettext_noop("Click to start drawing an epitrochoid. Drag left/right to change the size of the fixed circle, and up/down to change the size of the circle rolling outside of it. Use the size option to change where the pen is."),
|
||||
gettext_noop("Click to start drawing an epitrochoid. Drag left/right to change the size of the fixed circle, and up/down to change the size of the circle rolling outside of it. Then pen is within the rolling circle."),
|
||||
gettext_noop("Click to start drawing an epitrochoid. Drag left/right to change the size of the fixed circle, and up/down to change the size of the circle rolling outside of it. Then pen is on the edge of the rolling circle."),
|
||||
gettext_noop("Click to start drawing an epitrochoid. Drag left/right to change the size of the fixed circle, and up/down to change the size of the circle rolling outside of it. Then pen is outside the rolling circle."),
|
||||
/* Hypotrochoids */
|
||||
gettext_noop("Click to start drawing a hypotrochoid. Drag left/right to change the size of the fixed circle, and up/down to change the size of the circle rolling inside it. Use the size option to change where the pen is."),
|
||||
gettext_noop("Click to start drawing a hypotrochoid. Drag left/right to change the size of the fixed circle, and up/down to change the size of the circle rolling inside it. Then pen is within the rolling circle."),
|
||||
gettext_noop("Click to start drawing a hypotrochoid. Drag left/right to change the size of the fixed circle, and up/down to change the size of the circle rolling inside it. Then pen is on the edge of the rolling circle."),
|
||||
gettext_noop("Click to start drawing a hypotrochoid. Drag left/right to change the size of the fixed circle, and up/down to change the size of the circle rolling inside it. Then pen is outside the rolling circle."),
|
||||
};
|
||||
|
||||
|
||||
/* Sound effects (same for everyone) */
|
||||
enum {
|
||||
SND_DRAW_CLICK,
|
||||
SND_DRAW_RELEASE,
|
||||
NUM_SNDS
|
||||
};
|
||||
|
||||
Mix_Chunk *sound_effects[NUM_SNDS];
|
||||
|
||||
const char *sound_filenames[NUM_SNDS] = {
|
||||
"n_pt_persp_click.ogg", // FIXME
|
||||
"n_pt_persp_release.ogg", // FIXME
|
||||
};
|
||||
|
||||
Uint8 trochoids_size = 1;
|
||||
int trochoids_x, trochoids_y, dragged = 0;
|
||||
Uint32 trochoids_color = 0x00000000;
|
||||
int rotator_anim_a = 0;
|
||||
|
||||
/* Function prototypes: */
|
||||
Uint32 trochoids_api_version(void);
|
||||
int trochoids_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_level);
|
||||
int trochoids_get_tool_count(magic_api * api);
|
||||
SDL_Surface *trochoids_get_icon(magic_api * api, int which);
|
||||
char *trochoids_get_name(magic_api * api, int which);
|
||||
int trochoids_get_group(magic_api * api, int which);
|
||||
char *trochoids_get_description(magic_api * api, int which, int mode);
|
||||
int trochoids_requires_colors(magic_api * api, int which);
|
||||
int trochoids_modes(magic_api * api, int which);
|
||||
Uint8 trochoids_accepted_sizes(magic_api * api, int which, int mode);
|
||||
Uint8 trochoids_default_size(magic_api * api, int which, int mode);
|
||||
void trochoids_shutdown(magic_api * api);
|
||||
void trochoids_click(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
void trochoids_drag(magic_api * api, int which,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
int old_x, int old_y, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
void trochoids_work(magic_api * api, int which,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
int x, int y, SDL_Rect * update_rect, int guides);
|
||||
void trochoids_release(magic_api * api, int which,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
|
||||
SDL_Rect * update_rect);
|
||||
void trochoids_set_color(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, Uint8 r, Uint8 g, Uint8 b,
|
||||
SDL_Rect * update_rect);
|
||||
void trochoids_set_size(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas, SDL_Surface * last,
|
||||
Uint8 size, SDL_Rect * update_rect);
|
||||
void trochoids_line_callback(void *pointer, int tool, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
void trochoids_xorline_callback(void *pointer, int tool, SDL_Surface * canvas,
|
||||
SDL_Surface * snapshot, int x, int y);
|
||||
void trochoids_switchin(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas);
|
||||
void trochoids_switchout(magic_api * api, int which, int mode,
|
||||
SDL_Surface * canvas);
|
||||
int calc_lcm(int a, int b);
|
||||
|
||||
|
||||
Uint32 trochoids_api_version(void)
|
||||
{
|
||||
return (TP_MAGIC_API_VERSION);
|
||||
}
|
||||
|
||||
|
||||
int trochoids_init(magic_api * api, Uint8 disabled_features, Uint8 complexity_level ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int i;
|
||||
char filename[1024];
|
||||
|
||||
for (i = 0; i < NUM_SNDS; i++) {
|
||||
sound_effects[i] = NULL;
|
||||
}
|
||||
|
||||
if (disabled_features & MAGIC_FEATURE_SIZE) {
|
||||
tp_offers_sizes = 0;
|
||||
} else {
|
||||
tp_offers_sizes = 1;
|
||||
}
|
||||
|
||||
which_to_tool = which_to_tool_per_size_availability[tp_offers_sizes];
|
||||
|
||||
for (i = 0; i < NUM_SNDS; i++)
|
||||
{
|
||||
snprintf(filename, sizeof(filename), "%s/sounds/magic/%s", api->data_directory,
|
||||
sound_filenames[i]);
|
||||
sound_effects[i] = Mix_LoadWAV(filename);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
int trochoids_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (num_tools[tp_offers_sizes]);
|
||||
}
|
||||
|
||||
|
||||
SDL_Surface *trochoids_get_icon(magic_api * api, int which)
|
||||
{
|
||||
char filename[1024];
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/images/magic/%s",
|
||||
api->data_directory, icon_filenames[which_to_tool[which]]);
|
||||
|
||||
return (IMG_Load(filename));
|
||||
}
|
||||
|
||||
|
||||
char *trochoids_get_name(magic_api * api ATTRIBUTE_UNUSED, int which)
|
||||
{
|
||||
return (strdup(gettext(tool_names[which_to_tool[which]])));
|
||||
}
|
||||
|
||||
|
||||
int trochoids_get_group(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (MAGIC_TYPE_ARTISTIC);
|
||||
}
|
||||
|
||||
|
||||
char *trochoids_get_description(magic_api * api ATTRIBUTE_UNUSED, int which, int mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (strdup(gettext(tool_descriptions[which_to_tool[which]])));
|
||||
}
|
||||
|
||||
|
||||
int trochoids_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int trochoids_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return MODE_PAINT;
|
||||
}
|
||||
|
||||
Uint8 trochoids_accepted_sizes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return NUM_SIZES;
|
||||
}
|
||||
|
||||
|
||||
Uint8 trochoids_default_size(magic_api * api ATTRIBUTE_UNUSED,
|
||||
int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return DEFAULT_SIZE;
|
||||
}
|
||||
|
||||
|
||||
void trochoids_shutdown(magic_api * api ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_SNDS; i++) {
|
||||
if (sound_effects[i] != NULL) {
|
||||
Mix_FreeChunk(sound_effects[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void trochoids_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y,
|
||||
SDL_Rect * update_rect)
|
||||
{
|
||||
trochoids_x = x;
|
||||
trochoids_y = y;
|
||||
trochoids_drag(api, which, canvas, snapshot, x, y, x + (canvas->w / 20), y + (canvas->h / 20), update_rect);
|
||||
dragged = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Affect the canvas on drag: */
|
||||
void trochoids_drag(magic_api * api, int which,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
int old_x ATTRIBUTE_UNUSED, int old_y ATTRIBUTE_UNUSED,
|
||||
int x, int y, SDL_Rect * update_rect)
|
||||
{
|
||||
dragged = 1;
|
||||
trochoids_work(api, which, canvas, snapshot, x, y, update_rect, 1);
|
||||
}
|
||||
|
||||
void trochoids_work(magic_api * api, int which,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
int x, int y, SDL_Rect * update_rect, int guides) {
|
||||
int R, r, d, LCM;
|
||||
int px, py, px2, py2;
|
||||
float a, r_ratio, size;
|
||||
|
||||
which = which_to_tool[which];
|
||||
|
||||
/* Drag left/rigth to change radius of stator (fixed circle) */
|
||||
R = abs(trochoids_x - x);
|
||||
if (R < 20) {
|
||||
R = 20;
|
||||
}
|
||||
|
||||
R = (R / 10) * 10;
|
||||
|
||||
/* Drag down to increase radius of rotator (rolling circle) */
|
||||
r = abs(y - trochoids_y);
|
||||
if (r < 10) {
|
||||
r = 10;
|
||||
}
|
||||
|
||||
r = (r / 10) * 10;
|
||||
|
||||
/* Epitrochoid: rotator is outside the stator;
|
||||
Hypotrochoid: rotator is inside the stator */
|
||||
if (which == TOOL_HYPOTROCHOID_SIZES ||
|
||||
which == TOOL_HYPOTROCHOID_NOSIZES_1 ||
|
||||
which == TOOL_HYPOTROCHOID_NOSIZES_2 ||
|
||||
which == TOOL_HYPOTROCHOID_NOSIZES_3) {
|
||||
r = -r - 2;
|
||||
}
|
||||
|
||||
r_ratio = (float) (R + r) / (float) r;
|
||||
|
||||
/* Size option (or use of alternate tools, if --nomagicsizes)
|
||||
determines the distance from the center of the rotator
|
||||
that the pen draws */
|
||||
if (tp_offers_sizes) {
|
||||
size = trochoids_sizes_per_size_setting[trochoids_size];
|
||||
} else {
|
||||
size = trochoids_sizes_per_tool[which];
|
||||
}
|
||||
d = r * size;
|
||||
|
||||
/* Erase old before drawing new */
|
||||
|
||||
/* FIXME */
|
||||
update_rect->x = 0;
|
||||
update_rect->y = 0;
|
||||
update_rect->w = canvas->w;
|
||||
update_rect->h = canvas->h;
|
||||
|
||||
SDL_BlitSurface(snapshot, update_rect, canvas, update_rect);
|
||||
|
||||
/* Draw the lines */
|
||||
LCM = calc_lcm(r, R);
|
||||
for (a = 0; a < 360.0 * (float) (LCM / R); a++) {
|
||||
float a2 = (a + 1);
|
||||
|
||||
px = trochoids_x + (((R + r) * deg_cos(a)) + (d * deg_cos(r_ratio * a)));
|
||||
py = trochoids_y + (((R + r) * deg_sin(a)) - (d * deg_sin(r_ratio * a)));
|
||||
px2 = trochoids_x + (((R + r) * deg_cos((a2))) + (d * deg_cos(r_ratio * a2)));
|
||||
py2 = trochoids_y + (((R + r) * deg_sin((a2))) - (d * deg_sin(r_ratio * a2)));
|
||||
api->line((void *)api, which, canvas, snapshot, px, py, px2, py2, (20 * guides) + 1, trochoids_line_callback);
|
||||
}
|
||||
|
||||
if (guides) {
|
||||
/* When still dragging (before release), draw some "guides",
|
||||
showing the mechanism that would be used to generate the pattern */
|
||||
rotator_anim_a = (int) (atan2(y - trochoids_y, x - trochoids_x) / M_PI * 180.0);
|
||||
|
||||
for (a = 0; a < 360; a = a + 2) {
|
||||
/* Stator (fixed circle) */
|
||||
px = (int) ((float) trochoids_x + ((float) R * deg_cos(a)));
|
||||
py = (int) ((float) trochoids_y - ((float) R * deg_sin(a)));
|
||||
api->xorpixel(canvas, px, py);
|
||||
api->xorpixel(canvas, px + 1, py);
|
||||
api->xorpixel(canvas, px, py + 1);
|
||||
api->xorpixel(canvas, px + 1, py + 1);
|
||||
|
||||
/* Rotator (rolling circle) */
|
||||
px = (int) ((float) trochoids_x + ((R + r) * deg_cos(rotator_anim_a)) + ((float) r * deg_cos(a)));
|
||||
py = (int) ((float) trochoids_y + ((R + r) * deg_sin(rotator_anim_a)) - ((float) r * deg_sin(a)));
|
||||
api->xorpixel(canvas, px, py);
|
||||
api->xorpixel(canvas, px + 1, py);
|
||||
api->xorpixel(canvas, px, py + 1);
|
||||
api->xorpixel(canvas, px + 1, py + 1);
|
||||
|
||||
}
|
||||
px = (int) ((float) trochoids_x + ((R + r) * deg_cos(rotator_anim_a)) + ((float) d * deg_cos(0)));
|
||||
py = (int) ((float) trochoids_y + ((R + r) * deg_sin(rotator_anim_a)) - ((float) d * deg_sin(0)));
|
||||
for (int yy = -2; yy <= 2; yy++) {
|
||||
for (int xx = -2; xx <= 2; xx++) {
|
||||
api->putpixel(canvas, px + xx, py + yy, trochoids_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void trochoids_release(magic_api * api, int which,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
int x, int y, SDL_Rect * update_rect)
|
||||
{
|
||||
if (dragged == 0) {
|
||||
x += (canvas->w / 20);
|
||||
y += (canvas->h / 20);
|
||||
}
|
||||
|
||||
trochoids_work(api, which, canvas, snapshot, x, y, update_rect, 0);
|
||||
}
|
||||
|
||||
|
||||
void trochoids_set_color(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
|
||||
SDL_Surface * canvas ATTRIBUTE_UNUSED,
|
||||
SDL_Surface * snapshot ATTRIBUTE_UNUSED,
|
||||
Uint8 r, Uint8 g, Uint8 b,
|
||||
SDL_Rect * update_rect ATTRIBUTE_UNUSED)
|
||||
{
|
||||
trochoids_color = SDL_MapRGB(canvas->format, r, g, b);
|
||||
}
|
||||
|
||||
|
||||
void trochoids_set_size(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
|
||||
SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
|
||||
Uint8 size, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
|
||||
{
|
||||
trochoids_size = (size - 1); /* array index is 0-based, but Tux Paint returns between 1...{accepted sizes} */
|
||||
}
|
||||
|
||||
|
||||
void trochoids_line_callback(void *pointer ATTRIBUTE_UNUSED, int tool ATTRIBUTE_UNUSED,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
|
||||
int x, int y)
|
||||
{
|
||||
magic_api *api = (magic_api *) pointer;
|
||||
|
||||
api->putpixel(canvas, x, y, trochoids_color);
|
||||
}
|
||||
|
||||
void trochoids_xorline_callback(void *pointer ATTRIBUTE_UNUSED, int tool ATTRIBUTE_UNUSED,
|
||||
SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
|
||||
int x, int y)
|
||||
{
|
||||
magic_api *api = (magic_api *) pointer;
|
||||
|
||||
api->xorpixel(canvas, x, y);
|
||||
api->xorpixel(canvas, x + 1, y);
|
||||
api->xorpixel(canvas, x, y + 1);
|
||||
api->xorpixel(canvas, x + 1, y + 1);
|
||||
}
|
||||
|
||||
void trochoids_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
|
||||
SDL_Surface * canvas ATTRIBUTE_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void trochoids_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
|
||||
SDL_Surface * canvas ATTRIBUTE_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
int calc_lcm(int a, int b) {
|
||||
int max;
|
||||
|
||||
if (a > b) {
|
||||
max = a;
|
||||
} else {
|
||||
max = b;
|
||||
}
|
||||
|
||||
while ((max % a) != 0 || (max % b) != 0) {
|
||||
max++;
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue