【发布时间】:2012-07-10 02:54:49
【问题描述】:
已解决:请参阅 my answer。
我正在尝试找到一个位于圆弧内部的点,因此当发生填充时,它不会意外填充圆弧外的区域。只要两个角之间距离的绝对值:start和end;小于 PI 这有效(有几个极端的边缘情况,其中绘制的线非常接近以至于选择的点是这些线的一部分,但那是不同的一天......)。
我遇到的问题是,当开始角和结束角之间的距离的绝对值大于 PI 时,洪水发生在弧的外部而不是内部。许多例子之一是:如果弧从 0 开始并以 3PI/2 结束,则距离的绝对值为 3PI/2,泛光发生在角度之间,就好像绝对值距离为 PI/2 并泛滥整个屏幕除了吃豆人形的弧线。
编辑:
为避免混淆,这里是根据 allegro(以及一般的三角学)定义的弧:
void arc(BITMAP *bmp, int x, y, fixed ang1, ang2, int r, int color);
绘制圆弧 [减去初始/终止边或中心点],圆心 [原文如此] x,y 和半径 r,在 逆时针 [sic] 方向从角度 a1 开始,当它结束时 达到 a2....零在中心 [原文如此] 点的右侧,并且更大 值从那里逆时针旋转 [原文如此]。
方括号是我的符号。
我已经完成了从 allegro(愚蠢的)使用 fixed integers 到正确的 radian 值的转换。
结束编辑
void Arc::Draw(BITMAP* dest, int color, bool filled, bool showCenter, bool showSides) {
if(showSides || filled) {
Line initial(GetX(), GetY(), GetZ(), GetStartPoint().GetX(), GetStartPoint().GetY(), GetZ(), false);
initial.SetColor(color);
Line terminal(GetX(), GetY(), GetZ(), GetEndPoint().GetX(), GetEndPoint().GetY(), GetZ(), false);
terminal.SetColor(color);
initial.Draw(dest, initial.GetColor(), false);
terminal.Draw(dest, terminal.GetColor(), false);
} else if(showCenter) {
putpixel(dest, GetX(), GetY(), color);
}
//Draw arc first to prevent flood overflow.
arc(dest, GetX(), GetY(), AngleConverter::RadianToFixed(_startAngle), AngleConverter::RadianToFixed(_endAngle), _radius, color);
if(filled) {
double distance = std::fabs(this->_endAngle - this->_startAngle);
if(distance < a2de::A2DE_PI) {
Line displace(GetStartPoint(), GetEndPoint(), false);
Point displacePoint(displace.GetCenter());
floodfill(dest, displacePoint.GetX(), displacePoint.GetY(), color);
} else if(distance > a2de::A2DE_PI) {
Line displace(GetStartPoint(), GetEndPoint(), false);
Vector2D center_of_displacement(displace.GetCenter());
Vector2D center_point(this->_center);
Vector2D direction_of_center(center_of_displacement - center_point);
double angle = std::atan2(direction_of_center.GetY(), direction_of_center.GetX());
Vector2D flood_point = center_point - direction_of_center;
flood_point += angle;
double x = flood_point.GetX() > 0.0 ? std::ceilf(flood_point.GetX()) : std::floorf(flood_point.GetX());
double y = flood_point.GetY() > 0.0 ? std::ceilf(flood_point.GetY()) : std::floorf(flood_point.GetY());
floodfill(dest, x, y, color);
} else {
if(_startAngle == 0.0 || _endAngle == a2de::A2DE_2PI) {
floodfill(dest, GetX(), GetY() - 1, color);
} else if(_endAngle == 0.0 || _startAngle == a2de::A2DE_PI) {
floodfill(dest, GetX(), GetY() + 1, color);
}
}
}
}
【问题讨论】:
-
如果你只有角度/起始角度你不能定义弧,你应该有 1) 一个有符号的扫掠角,或顺时针/逆时针方向,说明弧的哪个部分从开始到结束是要考虑的
-
@FelicePollano 顺时针/逆时针方向由图形库自动确定。如果起始角度大于结束角度,则为顺时针方向,反之亦然。
-
您似乎使用术语“弧”来表示通常称为扇区的部分
-
@n.m.官方allegro 只绘制弧线(扇区的弯曲边界)。我正在扩展它,允许用户还绘制与其相邻的扇区的边。见arc
-
文档明确指出方向是逆时针的。这与您关于我认为是(a)错误和(b)您遇到困难的原因的方向的说法完全矛盾。你应该谈论有符号的角距离(逆时针为正,顺时针为负)。永远不要取它们的绝对值,这是没有意义的。
标签: c++ geometry trigonometry sector