Oblique, Dimetric & Trimetric seem to work!

This commit is contained in:
Bill Kendrick 2024-01-13 18:04:47 -08:00
parent fff19763e2
commit df6905a3c3
2 changed files with 74 additions and 45 deletions

View file

@ -39,19 +39,20 @@ https://tuxpaint.org/
Choose three vanishing points, and then draw lines that always Choose three vanishing points, and then draw lines that always
point towards them, or along the horizon defined by the first two. point towards them, or along the horizon defined by the first two.
+ WIP Orthographic (orthogonal) projection: + WIP Orthographic (orthogonal) projection:
- WIP Isometric ("Isometric Lines") - Isometric ("Isometric Lines")
Lines only go at evenly-spaced (120 degrees) angles (vertically Lines only go at evenly-spaced (120 degrees) angles (vertically
and diagonally). and diagonally).
- WIP Dimetric ("Dimetric Select" & "Dimetric Draw") - Dimetric ("Dimetric Select" & "Dimetric Draw")
Choose a single angle for both diagonals directions; lines may Choose a single angle for both diagonals directions; lines may
only go diagonally at those angles, or vertically. only go diagonally at those angles, or vertically.
- WIP Dimetric ("Trimetric Select" & "Trimetric Draw") - Dimetric ("Trimetric Select" & "Trimetric Draw")
Choose an angle for two diagonals directions; lines may Choose an angle for two diagonals directions; lines may
only go diagonally at those angles, or vertically. only go diagonally at those angles, or vertically.
- WIP Oblique ("Oblique Select" & "Oblique Draw") - Oblique ("Oblique Select" & "Oblique Draw")
Choose an angle for a single diagonal direction; lines may Choose an angle for a single diagonal direction; lines may
only go diagonally at that one angle, vertically, or only go diagonally at that one angle, vertically, or
horizontally. horizontally.
[WIP Need icons & sounds & docs]
+ None of these tools are available when in "novice" complexity mode + None of these tools are available when in "novice" complexity mode
(see above). (see above).
+ "Select" tools (to edit vanishing points or angles) are not offered + "Select" tools (to edit vanishing points or angles) are not offered

View file

@ -217,7 +217,7 @@ const char *tool_names[NUM_TOOLS] = {
gettext_noop("Oblique Select"), gettext_noop("Oblique Select"),
gettext_noop("Oblique Draw"), gettext_noop("Oblique Draw"),
"", "",
gettext_noop("Oblique Draw Left"), gettext_noop("Oblique Draw Right"),
}; };
@ -428,9 +428,11 @@ int n_pt_persp_init(magic_api * api, Uint8 disabled_features ATTRIBUTE_UNUSED, U
/* Set default angles: */ /* Set default angles: */
dim_ang = 45.0 * M_PI / 180.0; dim_ang = 45.0 * M_PI / 180.0;
tri_ang[0] = 15 * M_PI / 180.0;
tri_ang[1] = 75 * M_PI / 180.0; tri_ang[0] = 30 * M_PI / 180.0;
tri_ang[1] = 165 * M_PI / 180.0;
tri_ang_chosen = 0; tri_ang_chosen = 0;
oblq_ang = -45 * M_PI / 180.0; oblq_ang = -45 * M_PI / 180.0;
oblqb_ang = 45 * M_PI / 180.0; oblqb_ang = 45 * M_PI / 180.0;
@ -631,18 +633,18 @@ void n_pt_persp_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
if (x < canvas->w / 2) { if (x < canvas->w / 2) {
if (y < canvas->h / 2) { if (y < canvas->h / 2) {
/* top left */ /* top left */
tri_ang_chosen = 0; tri_ang_chosen = 1;
} else { } else {
/* bottom left */ /* bottom left */
tri_ang_chosen = 1; tri_ang_chosen = 0;
} }
} else { } else {
if (y < canvas->h / 2) { if (y < canvas->h / 2) {
/* top right */ /* top right */
tri_ang_chosen = 1; tri_ang_chosen = 0;
} else { } else {
/* bottom right */ /* bottom right */
tri_ang_chosen = 0; tri_ang_chosen = 1;
} }
} }
} }
@ -997,29 +999,31 @@ void n_pt_persp_drag(magic_api * api, int which,
n_pt_persp_vanish_pt_moved(api, which, canvas, update_rect); n_pt_persp_vanish_pt_moved(api, which, canvas, update_rect);
} else if (which == TOOL_TRI_SELECT) { } else if (which == TOOL_TRI_SELECT) {
/* Trimetric - select */ /* Trimetric - select */
float ang; float ang, offset;
if (tri_ang_chosen == 0) {
y = canvas->h - y;
}
if (x < canvas->w / 2) {
x = canvas->w - x;
y = canvas->h - y;
}
ang = atan2f(canvas->h / 2 - y, x - canvas->w / 2); ang = atan2f(canvas->h / 2 - y, x - canvas->w / 2);
#ifdef DEBUG
printf("cursor ang = %.2f -> ", ang * 180.0 / M_PI);
#endif
if (ang > M_PI) { if (ang > M_PI) {
ang -= M_PI; ang -= M_PI;
} else if (ang < -M_PI) { } else if (ang < 0) {
ang += M_PI; ang += M_PI;
} }
#ifdef DEBUG
printf("%.2f -> clipping for %d -> ", ang * 180.0 / M_PI, tri_ang_chosen);
#endif
if (ang < MIN_AXONOMETRIC_ANGLE) { offset = ((M_PI / 2) * tri_ang_chosen);
ang = MIN_AXONOMETRIC_ANGLE; if (ang < MIN_AXONOMETRIC_ANGLE + offset) {
} else if (ang > MAX_AXONOMETRIC_ANGLE) { ang = MIN_AXONOMETRIC_ANGLE + offset;
ang = MAX_AXONOMETRIC_ANGLE; } else if (ang > MAX_AXONOMETRIC_ANGLE + offset) {
ang = MAX_AXONOMETRIC_ANGLE + offset;
} }
#ifdef DEBUG
printf("%.2f -> \n", ang * 180.0 / M_PI);
#endif
tri_ang[tri_ang_chosen] = ang; tri_ang[tri_ang_chosen] = ang;
@ -1198,39 +1202,58 @@ void n_pt_persp_work(magic_api * api, int tool,
valid_angles[2] = M_PI - dim_ang; valid_angles[2] = M_PI - dim_ang;
} else if (tool == TOOL_TRI_DRAW) { } else if (tool == TOOL_TRI_DRAW) {
/* trimetric diagonals */ /* trimetric diagonals */
valid_angles[1] = tri_ang[0]; valid_angles[1] = M_PI - tri_ang[0];
valid_angles[2] = tri_ang[1]; valid_angles[2] = M_PI - tri_ang[1];
} else if (tool == TOOL_OBLQ_DRAW) { } else if (tool == TOOL_OBLQ_DRAW) {
/* horizontal */ /* horizontal */
valid_angles[1] = 0.0; valid_angles[1] = 0.0;
/* oblique diagonal */ /* oblique diagonal */
valid_angles[2] = oblq_ang; valid_angles[2] = M_PI - oblq_ang;
} else if (tool == TOOL_OBLQ_DRAW_ALT) { } else if (tool == TOOL_OBLQ_DRAW_ALT) {
/* horizontal */ /* horizontal */
valid_angles[1] = 0.0; valid_angles[1] = 0.0;
/* oblique diagonal */ /* oblique diagonal */
valid_angles[2] = oblqb_ang; valid_angles[2] = M_PI - oblqb_ang;
} }
/* And the opposite directions */ /* And the opposite directions */
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
valid_angles[i + 3] = valid_angles[i] + M_PI; valid_angles[i + 3] = valid_angles[i] + M_PI;
if (valid_angles[i + 3] > M_PI * 2) {
valid_angles[i] -= (M_PI * 2);
}
} }
// FIXME needs more work #ifdef DEBUG
printf("\n");
#endif
for (i = 0; i < 6; i++) {
#ifdef DEBUG
printf(" %.2f -> ", valid_angles[i] * 180.0 / M_PI);
#endif
if (valid_angles[i] > M_PI) {
valid_angles[i] -= (M_PI * 2);
}
#ifdef DEBUG
printf("%.2f\n", valid_angles[i] * 180.0 / M_PI);
#endif
}
cursor_angle = atan2f(y - line_start_y, x - line_start_x); cursor_angle = atan2f(line_start_y- y, line_start_x - x);
#ifdef DEBUG
printf("cursor ang = %.2f\n", cursor_angle * 180.0 / M_PI); printf("cursor ang = %.2f\n", cursor_angle * 180.0 / M_PI);
#endif
best_angle_idx = -1; best_angle_idx = -1;
best_diff = M_PI * 2; best_diff = M_PI * 2;
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
#ifdef DEBUG
printf(" #%d %.2f vs %.2f\n", i, cursor_angle * 180.0 / M_PI, valid_angles[i] * 180.0 / M_PI);
#endif
diff = fabs(cursor_angle - valid_angles[i]); diff = fabs(cursor_angle - valid_angles[i]);
if (diff < best_diff) {
best_angle_idx = i;
best_diff = diff;
}
diff = fabs((cursor_angle - (M_PI * 2)) - valid_angles[i]);
if (diff < best_diff) { if (diff < best_diff) {
best_angle_idx = i; best_angle_idx = i;
best_diff = diff; best_diff = diff;
@ -1243,8 +1266,9 @@ void n_pt_persp_work(magic_api * api, int tool,
} }
ang = valid_angles[best_angle_idx]; ang = valid_angles[best_angle_idx];
#ifdef DEBUG
printf("best ang = [%d] %.2f\n", best_angle_idx, ang * 180.0 / M_PI); printf("best ang = [%d] %.2f\n", best_angle_idx, ang * 180.0 / M_PI);
#endif
x1 = line_start_x; x1 = line_start_x;
y1 = line_start_y; y1 = line_start_y;
@ -1625,18 +1649,22 @@ void n_pt_persp_draw_points(magic_api * api, int tool, SDL_Surface * canvas) {
/* angle 1 */ /* angle 1 */
x1 = cos(tri_ang[0]) * canvas->w; x1 = cos(tri_ang[0]) * canvas->w;
y1 = sin(tri_ang[0]) * canvas->w; y1 = sin(tri_ang[0]) * canvas->w;
api->line((void *) api, tool, canvas, NULL, for (i = 0; i < ((tri_ang_chosen == 0) * 3) + 1; i++) {
canvas->w / 2 - x1, canvas->h / 2 - y1, api->line((void *) api, tool, canvas, NULL,
canvas->w / 2 + x1, canvas->h / 2 + y1, 12, canvas->w / 2 - x1 + i, canvas->h / 2 + y1,
n_pt_persp_line_xor_callback); canvas->w / 2 + x1 + i, canvas->h / 2 - y1, 12,
n_pt_persp_line_xor_callback);
}
/* angle 2 */ /* angle 2 */
x1 = cos(tri_ang[1]) * canvas->w; x1 = cos(tri_ang[1]) * canvas->w;
y1 = -sin(tri_ang[1]) * canvas->w; y1 = sin(tri_ang[1]) * canvas->w;
api->line((void *) api, tool, canvas, NULL, for (i = 0; i < ((tri_ang_chosen == 1) * 3) + 1; i++) {
canvas->w / 2 - x1, canvas->h / 2 - y1, api->line((void *) api, tool, canvas, NULL,
canvas->w / 2 + x1, canvas->h / 2 + y1, 12, canvas->w / 2 - x1 + i, canvas->h / 2 + y1,
n_pt_persp_line_xor_callback); canvas->w / 2 + x1 + i, canvas->h / 2 - y1, 12,
n_pt_persp_line_xor_callback);
}
} else if (tool == TOOL_OBLQ_SELECT || tool == TOOL_OBLQ_SELECT_ALT) { } else if (tool == TOOL_OBLQ_SELECT || tool == TOOL_OBLQ_SELECT_ALT) {
/* Oblique */ /* Oblique */