这是图片代码(只是一个占位符):
struct Point {
int x, y;
};
struct Image {};
using Color = int;
void setPixel(Image &, Color, Point) {
// ...
}
void horiLine(Image &image, Color color, Point first, int last) {
while (first.x <= last) {
setPixel(image, color, first);
first.x++;
}
}
void vertLine(Image &image, Color color, Point first, int last) {
while (first.y <= last) {
setPixel(image, color, first);
first.y++;
}
}
这里是中点厚圆算法:
void midpointCircleThick(
Image &image,
Color color,
Point center,
int innerRadius,
int outerRadius
) {
int innerX = innerRadius;
int outerX = outerRadius;
int posY = 0;
int innerErr = 1 - innerRadius;
int outerErr = 1 - outerRadius;
while (outerX >= posY) {
horiLine(image, color, {center.x + innerX, center.y + posY}, center.x + outerX);
vertLine(image, color, {center.x + posY, center.y + innerX}, center.y + outerX);
horiLine(image, color, {center.x - outerX, center.y + posY}, center.x - innerX);
vertLine(image, color, {center.x - posY, center.y + innerX}, center.y + outerX);
horiLine(image, color, {center.x - outerX, center.y - posY}, center.x - innerX);
vertLine(image, color, {center.x - posY, center.y - outerX}, center.y - innerX);
horiLine(image, color, {center.x + innerX, center.y - posY}, center.x + outerX);
vertLine(image, color, {center.x + posY, center.y - outerX}, center.y - innerX);
posY++;
if (outerErr < 0) {
outerErr += 2 * posY + 1;
} else {
outerX--;
outerErr += 2 * (posY - outerX) + 1;
}
if (posY > innerRadius) {
innerX = posY;
} else {
if (innerErr < 0) {
innerErr += 2 * posY + 1;
} else {
innerX--;
innerErr += 2 * (posY - innerX) + 1;
}
}
}
}
这是中点椭圆算法:
void midpointEllipse(
Image &image,
Color color,
Point center,
Point radius
) {
Point pos = {radius.x, 0};
Point delta = {
2 * radius.y * radius.y * pos.x,
2 * radius.x * radius.x * pos.y
};
int err = radius.x * radius.x
- radius.y * radius.y * radius.x
+ (radius.y * radius.y) / 4;
while (delta.y < delta.x) {
setPixel(image, color, {center.x + pos.x, center.y + pos.y});
setPixel(image, color, {center.x + pos.x, center.y - pos.y});
setPixel(image, color, {center.x - pos.x, center.y + pos.y});
setPixel(image, color, {center.x - pos.x, center.y - pos.y});
pos.y++;
if (err < 0) {
delta.y += 2 * radius.x * radius.x;
err += delta.y + radius.x * radius.x;
} else {
pos.x--;
delta.y += 2 * radius.x * radius.x;
delta.x -= 2 * radius.y * radius.y;
err += delta.y - delta.x + radius.x * radius.x;
}
}
err = radius.x * radius.x * (pos.y * pos.y + pos.y)
+ radius.y * radius.y * (pos.x - 1) * (pos.x - 1)
- radius.y * radius.y * radius.x * radius.x;
while (pos.x >= 0) {
setPixel(image, color, {center.x + pos.x, center.y + pos.y});
setPixel(image, color, {center.x + pos.x, center.y - pos.y});
setPixel(image, color, {center.x - pos.x, center.y + pos.y});
setPixel(image, color, {center.x - pos.x, center.y - pos.y});
pos.x--;
if (err > 0) {
delta.x -= 2 * radius.y * radius.y;
err += radius.y * radius.y - delta.x;
} else {
pos.y++;
delta.y += 2 * radius.x * radius.x;
delta.x -= 2 * radius.y * radius.y;
err += delta.y - delta.x + radius.y * radius.y;
}
}
}
我试图结合这两个算法,目前这就是我的成果。在我不确定代码的地方我留了一些 ?
。我很清楚这里有混乱和重复的部分,但在我担心代码看起来如何之前,我只想让它能工作。
void midpointEllipseThick(
Image &image,
Color color,
Point center,
Point innerRadius,
Point outerRadius
) {
int innerX = innerRadius.x;
int outerX = outerRadius.x;
int posY = 0;
Point innerDelta = {
2 * innerRadius.y * innerRadius.y * innerX,
2 * innerRadius.x * innerRadius.x * posY
};
Point outerDelta = {
2 * outerRadius.y * outerRadius.y * outerX,
2 * outerRadius.x * outerRadius.x * posY
};
int innerErr = innerRadius.x * innerRadius.x
- innerRadius.y * innerRadius.y * innerRadius.x
+ (innerRadius.y * innerRadius.y) / 4;
int outerErr = outerRadius.x * outerRadius.x
- outerRadius.y * outerRadius.y * outerRadius.x
+ (outerRadius.y * outerRadius.y) / 4;
while (outerDelta.y < outerDelta.x) { // ?
horiLine(image, color, {center.x + innerX, center.y + posY}, center.x + outerX);
vertLine(image, color, {center.x + posY, center.y + innerX}, center.y + outerX);
horiLine(image, color, {center.x - outerX, center.y + posY}, center.x - innerX);
vertLine(image, color, {center.x - posY, center.y + innerX}, center.y + outerX);
horiLine(image, color, {center.x - outerX, center.y - posY}, center.x - innerX);
vertLine(image, color, {center.x - posY, center.y - outerX}, center.y - innerX);
horiLine(image, color, {center.x + innerX, center.y - posY}, center.x + outerX);
vertLine(image, color, {center.x + posY, center.y - outerX}, center.y - innerX);
posY++;
if (outerErr < 0) {
outerDelta.y += 2 * outerRadius.x * outerRadius.x;
outerErr += outerDelta.y + outerRadius.x * outerRadius.x;
} else {
outerX--;
outerDelta.y += 2 * outerRadius.x * outerRadius.x;
outerDelta.x -= 2 * outerRadius.y * outerRadius.y;
outerErr += outerDelta.y - outerDelta.x + outerRadius.x * outerRadius.x;
}
// ?
// if (posY > innerRadius.y) {
// innerX = posY;
// } else {
if (innerErr < 0) {
innerDelta.y += 2 * innerRadius.x * innerRadius.x;
innerErr += innerDelta.y + innerRadius.x * innerRadius.x;
} else {
innerX--;
innerDelta.y += 2 * innerRadius.x * innerRadius.x;
innerDelta.x -= 2 * innerRadius.y * innerRadius.y;
innerErr += innerDelta.y - innerDelta.x + innerRadius.x * innerRadius.x;
}
// }
}
innerErr = innerRadius.x * innerRadius.x * (posY * posY + posY)
+ innerRadius.y * innerRadius.y * (innerX - 1) * (innerX - 1)
- innerRadius.y * innerRadius.y * innerRadius.x * innerRadius.x;
outerErr = outerRadius.x * outerRadius.x * (posY * posY + posY)
+ outerRadius.y * outerRadius.y * (outerX - 1) * (outerX - 1)
- outerRadius.y * outerRadius.y * outerRadius.x * outerRadius.x;
while (outerX >= 0) { // ?
horiLine(image, color, {center.x + innerX, center.y + posY}, center.x + outerX);
vertLine(image, color, {center.x + posY, center.y + innerX}, center.y + outerX);
horiLine(image, color, {center.x - outerX, center.y + posY}, center.x - innerX);
vertLine(image, color, {center.x - posY, center.y + innerX}, center.y + outerX);
horiLine(image, color, {center.x - outerX, center.y - posY}, center.x - innerX);
vertLine(image, color, {center.x - posY, center.y - outerX}, center.y - innerX);
horiLine(image, color, {center.x + innerX, center.y - posY}, center.x + outerX);
vertLine(image, color, {center.x + posY, center.y - outerX}, center.y - innerX);
outerX--; // ?
innerX--;
if (outerErr > 0) {
outerDelta.x -= 2 * outerRadius.y * outerRadius.y;
outerErr += outerRadius.y * outerRadius.y - outerDelta.x;
} else {
posY++;
outerDelta.y += 2 * outerRadius.x * outerRadius.x;
outerDelta.x -= 2 * outerRadius.y * outerRadius.y;
outerErr += outerDelta.y - outerDelta.x + outerRadius.y * outerRadius.y;
}
// ?
// if (innerX < -innerRadius.x) {
// } else {
if (outerErr > 0) {
innerDelta.x -= 2 * innerRadius.y * innerRadius.y;
innerErr += innerRadius.y * innerRadius.y - innerDelta.x;
} else {
posY++;
innerDelta.y += 2 * innerRadius.x * innerRadius.x;
innerDelta.x -= 2 * innerRadius.y * innerRadius.y;
outerErr += innerDelta.y - innerDelta.x + innerRadius.y * innerRadius.y;
}
// }
}
}
这里有一个内径为22、外径为24的粗圆:
这里有一个半径为{32, 24}的椭圆:
这里是一个(应该是)内径为{30, 22}、外径为{32, 24}的粗椭圆:
我已经接近成功,但还差一点。有没有比我更了解这方面的人能帮我完成最后的工作呢?