📄 gd_arc_f_buggy.c
字号:
pt[1].y = cy; pt[2].x = cx + (flip_x ? (-pt[2].x) : pt[2].x); pt[2].y = cy + (flip_y ? (-pt[2].y) : pt[2].y); gdImageFilledPolygon (im, pt, 3, color); gdImagePolygon (im, pt, 3, color); pt[0] = pt[3]; pt[1] = pt[4]; pt[2] = pt[5]; } if (((s_cos * hs) > (s_sin * ws)) && ((e_cos * hs) < (e_sin * ws))) { /* the points are on different parts of the curve... * this is too tricky to try to handle, so divide and conquer: */ pt[3] = pt[0]; pt[4] = pt[1]; pt[5] = pt[2]; pt[0].x = cx + (flip_x ? (-pt[0].x) : pt[0].x); pt[0].y = cy + (flip_y ? (-pt[0].y) : pt[0].y); pt[1].x = cx + (flip_x ? (-pt[1].x) : pt[1].x); pt[1].y = cy + (flip_y ? (-pt[1].y) : pt[1].y); pt[2].x = cx + (flip_x ? (-pt[2].x) : pt[2].x); pt[2].y = cy + (flip_y ? (-pt[2].y) : pt[2].y); gdImageFilledPolygon (im, pt, 3, color); gdImagePolygon (im, pt, 3, color); pt[0] = pt[3]; pt[2] = pt[4]; conquer = 1; } if (conquer || (((s_cos * hs) > (s_sin * ws)) && ((e_cos * hs) > (e_sin * ws)))) { /* This is the best bit... */ /* steep line + ellipse */ /* go up & left from pt[0] to pt[2] */ x2 = w; y2 = 0; /* Starting point is exactly on ellipse */ g = x2 - 1; g = g * g * hs + 4 * ws - whs; while ((x2 * hs) > (y2 * ws)) /* Keep |tangent| > 1 */ { if ((s_sin * x2) <= (y2 * s_cos)) break; y2 += 2; g += ws * 4 * (y2 + 1); if (g > 0) /* Need to drop */ { x2 -= 2; g -= hs * 4 * x2; } } lx2 = x2; ly2 = y2; lg = lx2 * (pt[0].y - pt[2].y) - ly2 * (pt[0].x - pt[2].x); lg = (lx2 - 1) * (pt[0].y - pt[2].y) - (ly2 + 2) * (pt[0].x - pt[2].x) - lg; while (y2 < (2 * pt[2].y)) { y2 += 2; g += ws * 4 * (y2 + 1); if (g > 0) /* Need to drop */ { x2 -= 2; g -= hs * 4 * x2; } ly2 += 2; lg -= 2 * (pt[0].x - pt[2].x); if (lg < 0) /* Need to drop */ { lx2 -= 2; lg -= 2 * (pt[0].y - pt[2].y); } y = (int) (y2 / 2); for (x = (int) (lx2 / 2); x <= (int) (x2 / 2); x++) { gdImageSetPixel (im, ((flip_x) ? (cx - x) : (cx + x)), ((flip_y) ? (cy - y) : (cy + y)), color); } } } if (conquer) { pt[0] = pt[4]; pt[2] = pt[5]; } if (conquer || (((s_cos * hs) < (s_sin * ws)) && ((e_cos * hs) < (e_sin * ws)))) { /* This is the best bit... */ /* gradual line + ellipse */ /* go down & right from pt[2] to pt[0] */ x2 = 0; y2 = h; /* Starting point is exactly on ellipse */ g = y2 - 1; g = g * g * ws + 4 * hs - whs; while ((x2 * hs) < (y2 * ws)) { x2 += 2; g += hs * 4 * (x2 + 1); if (g > 0) /* Need to drop */ { y2 -= 2; g -= ws * 4 * y2; } if ((e_sin * x2) >= (y2 * e_cos)) break; } lx2 = x2; ly2 = y2; lg = lx2 * (pt[0].y - pt[2].y) - ly2 * (pt[0].x - pt[2].x); lg = (lx2 + 2) * (pt[0].y - pt[2].y) - (ly2 - 1) * (pt[0].x - pt[2].x) - lg; while (x2 < (2 * pt[0].x)) { x2 += 2; g += hs * 4 * (x2 + 1); if (g > 0) /* Need to drop */ { y2 -= 2; g -= ws * 4 * y2; } lx2 += 2; lg += 2 * (pt[0].y - pt[2].y); if (lg < 0) /* Need to drop */ { ly2 -= 2; lg += 2 * (pt[0].x - pt[2].x); } x = (int) (x2 / 2); for (y = (int) (ly2 / 2); y <= (int) (y2 / 2); y++) { gdImageSetPixel (im, ((flip_x) ? (cx - x) : (cx + x)), ((flip_y) ? (cy - y) : (cy + y)), color); } } }}static gdPointgdArcClosest (int width, int height, int angle){ gdPoint pt; int flip_x = 0; int flip_y = 0; long a_sin = 0; long a_cos = 0; long w; /* a * 2 */ long h; /* b * 2 */ long x2; /* x * 2 */ long y2; /* y * 2 */ long ws; /* (a * 2)^2 */ long hs; /* (b * 2)^2 */ long whs; /* (a * 2)^2 * (b * 2)^2 */ long g; /* decision variable */ w = (long) ((width & 1) ? (width + 1) : (width)); h = (long) ((height & 1) ? (height + 1) : (height)); while (angle < 0) angle += 360; while (angle >= 360) angle -= 360; if (angle == 0) { pt.x = w / 2; pt.y = 0; return (pt); } if (angle == 90) { pt.x = 0; pt.y = h / 2; return (pt); } if (angle == 180) { pt.x = -w / 2; pt.y = 0; return (pt); } if (angle == 270) { pt.x = 0; pt.y = -h / 2; return (pt); } pt.x = 0; pt.y = 0; if ((angle > 90) && (angle < 180)) { angle = 180 - angle; flip_x = 1; } if ((angle > 180) && (angle < 270)) { angle = angle - 180; flip_x = 1; flip_y = 1; } if ((angle > 270) && (angle < 360)) { angle = 360 - angle; flip_y = 1; } a_sin = (long) ((double) 32768 * sin ((double) angle * M_PI / (double) 180)); a_cos = (long) ((double) 32768 * cos ((double) angle * M_PI / (double) 180)); ws = w * w; hs = h * h; whs = 1; while ((ws > 32768) || (hs > 32768)) { ws = (ws + 1) / 2; /* Unfortunate limitations on integers makes */ hs = (hs + 1) / 2; /* drawing large ellipses problematic... */ whs *= 2; } while ((ws * hs) > (0x04000000L / whs)) { ws = (ws + 1) / 2; hs = (hs + 1) / 2; whs *= 2; } whs *= ws * hs; if ((a_cos * hs) > (a_sin * ws)) { x2 = w; y2 = 0; /* Starting point is exactly on ellipse */ g = x2 - 1; g = g * g * hs + 4 * ws - whs; while ((x2 * hs) > (y2 * ws)) /* Keep |tangent| > 1 */ { y2 += 2; g += ws * 4 * (y2 + 1); if (g > 0) /* Need to drop */ { x2 -= 2; g -= hs * 4 * x2; } if ((a_sin * x2) <= (y2 * a_cos)) { pt.x = (int) (x2 / 2); pt.y = (int) (y2 / 2); break; } } } else { x2 = 0; y2 = h; /* Starting point is exactly on ellipse */ g = y2 - 1; g = g * g * ws + 4 * hs - whs; while ((x2 * hs) < (y2 * ws)) { x2 += 2; g += hs * 4 * (x2 + 1); if (g > 0) /* Need to drop */ { y2 -= 2; g -= ws * 4 * y2; } if ((a_sin * x2) >= (y2 * a_cos)) { pt.x = (int) (x2 / 2); pt.y = (int) (y2 / 2); break; } } } if (flip_x) pt.x = -pt.x; if (flip_y) pt.y = -pt.y; return (pt);}#include "gd.h"#include <string.h>#include <math.h>#define WIDTH 500#define HEIGHT 300intmain (int argc, char *argv[]){ gdImagePtr im = gdImageCreate (WIDTH, HEIGHT); int white = gdImageColorResolve (im, 0xFF, 0xFF, 0xFF), black = gdImageColorResolve (im, 0, 0, 0), red = gdImageColorResolve (im, 0xFF, 0xA0, 0xA0); FILE *out; /* filled arc - circle */ gdImageFilledArc (im, WIDTH / 5, HEIGHT / 4, 200, 200, 45, 90, red, gdPie); gdImageArc (im, WIDTH / 5, HEIGHT / 4, 200, 200, 45, 90, black); /* filled arc - ellipse */ gdImageFilledArc (im, WIDTH / 2, HEIGHT / 4, 200, 150, 45, 90, red, gdPie); gdImageArc (im, WIDTH / 2, HEIGHT / 4, 200, 150, 45, 90, black); /* reference lines */ gdImageLine (im, 0, HEIGHT / 4, WIDTH, HEIGHT / 4, black); gdImageLine (im, WIDTH / 5, 0, WIDTH / 5, HEIGHT, black); gdImageLine (im, WIDTH / 2, 0, WIDTH / 2, HEIGHT, black); gdImageLine (im, WIDTH / 2, HEIGHT / 4, WIDTH / 2 + 300, HEIGHT / 4 + 300, black); gdImageLine (im, WIDTH / 5, HEIGHT / 4, WIDTH / 5 + 300, HEIGHT / 4 + 300, black); /* TBB: Write img to test/arctest.png */ out = fopen ("test/arctest.png", "wb"); if (!out) { php_gd_error("Can't create test/arctest.png"); exit (1); } gdImagePng (im, out); fclose (out); php_gd_error("Test image written to test/arctest.png"); /* Destroy it */ gdImageDestroy (im); return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -