我从这里实现了 Xiaolin Wu 圆算法:https://create.stephan-brumme.com/antialiased-circle/在 C++ 中:
float radiusX = endRadius;
float radiusY = endRadius;
float radiusX2 = radiusX * radiusX;
float radiusY2 = radiusY * radiusY;
float maxTransparency = 127;
float quarter = roundf(radiusX2 / sqrtf(radiusX2 + radiusY2));
for(float _x = 0; _x <= quarter; _x++) {
float _y = radiusY * sqrtf(1 - _x * _x / radiusX2);
float error = _y - floorf(_y);
float transparency = roundf(error * maxTransparency);
int alpha = transparency;
int alpha2 = maxTransparency - transparency;
setPixel4(x, y, _x, floorf(_y), r, g, b, alpha, data, areasData, false);
setPixel4(x, y, _x, floorf(_y) - 1, r, g, b, alpha2, data, areasData, false);
}
quarter = roundf(radiusY2 / sqrtf(radiusX2 + radiusY2));
for(float _y = 0; _y <= quarter; _y++) {
float _x = radiusX * sqrtf(1 - _y * _y / radiusY2);
float error = _x - floorf(_x);
float transparency = roundf(error * maxTransparency);
int alpha = transparency;
int alpha2 = maxTransparency - transparency;
setPixel4(x, y, floorf(_x), _y, r, g, b, alpha, data, areasData, false);
setPixel4(x, y, floorf(_x) - 1, _y, r, g, b, alpha2, data, areasData, false);
}
x,y 为圆心坐标。
在我看来它看起来不错:
但是,我需要填充圆圈。也许我错了,但我开发了一个简单的算法:从 1 迭代到半径并画一个圆。它看起来像这样:
奇怪。所以,为了解决这个问题,我还将透明度设置为最大,直到我到达最后一个半径(所以它是一个外圆):
如您所见,外层和其他层之间有奇怪的孔。我试过制作两个外层和类似的东西,但没有得到正确的结果。
这是代码的最终版本:
for(int cradius = startRadius; cradius <= endRadius; cradius++) {
bool last = cradius == endRadius;
float radiusX = cradius;
float radiusY = cradius;
float radiusX2 = radiusX * radiusX;
float radiusY2 = radiusY * radiusY;
float maxTransparency = 127;
float quarter = roundf(radiusX2 / sqrtf(radiusX2 + radiusY2));
for(float _x = 0; _x <= quarter; _x++) {
float _y = radiusY * sqrtf(1 - _x * _x / radiusX2);
float error = _y - floorf(_y);
float transparency = roundf(error * maxTransparency);
int alpha = transparency;
int alpha2 = maxTransparency - transparency;
if(!last) {
alpha = maxTransparency;
alpha2 = maxTransparency;
}
setPixel4(x, y, _x, floorf(_y), r, g, b, alpha, data, areasData, false);
setPixel4(x, y, _x, floorf(_y) - 1, r, g, b, alpha2, data, areasData, false);
}
quarter = roundf(radiusY2 / sqrtf(radiusX2 + radiusY2));
for(float _y = 0; _y <= quarter; _y++) {
float _x = radiusX * sqrtf(1 - _y * _y / radiusY2);
float error = _x - floorf(_x);
float transparency = roundf(error * maxTransparency);
int alpha = transparency;
int alpha2 = maxTransparency - transparency;
if(!last) {
alpha = maxTransparency;
alpha2 = maxTransparency;
}
setPixel4(x, y, floorf(_x), _y, r, g, b, alpha, data, areasData, false);
setPixel4(x, y, floorf(_x) - 1, _y, r, g, b, alpha2, data, areasData, false);
}
}
我该如何解决这个问题?
编辑:
因为我不能使用 flood-fill 来填充圆圈(我绘制的区域可能不是单色背景,我需要混合这些颜色)我实现了简单的方法来连接点和线:
我在 setPixel4 方法中添加了 2 个 drawLine 调用:
void setPixel4(int x, int y, int deltaX, int deltaY, int r, int g, int b, int a, unsigned char* data, unsigned char* areasData, bool blendColor) {
drawLine(x - deltaX, y - deltaY, x + deltaX, y + deltaY, r, g, b, 127, data, areasData); //maxTransparency
drawLine(x + deltaX, y - deltaY, x - deltaX, y + deltaY, r, g, b, 127, data, areasData); //maxTransparency
setPixelWithCheckingArea(x + deltaX, y + deltaY, r, g, b, a, data, areasData, blendColor);
setPixelWithCheckingArea(x - deltaX, y + deltaY, r, g, b, a, data, areasData, blendColor);
setPixelWithCheckingArea(x + deltaX, y - deltaY, r, g, b, a, data, areasData, blendColor);
setPixelWithCheckingArea(x - deltaX, y - deltaY, r, g, b, a, data, areasData, blendColor);
}
它看起来和第三张图一模一样。我认为里面的这些白色像素是由外圈(来自 xiaolin wu 算法)本身引起的。
编辑 2:
感谢@JaMiT,我改进了我的代码并且它适用于一个圆圈,但是当我有更多的相互重叠时失败了。一、新代码:
void drawFilledCircle(int x, int y, int startRadius, int endRadius, int r, int g, int b, int a, unsigned char* data, unsigned char* areasData, int startAngle, int endAngle, bool blendColor) {
assert(startAngle <= endAngle);
assert(startRadius <= endRadius);
dfBufferCounter = 0;
for(int i = 0; i < DRAW_FILLED_CIRCLE_BUFFER_SIZE; i++) {
drawFilledCircleBuffer[i] = -1;
}
for(int cradius = endRadius; cradius >= startRadius; cradius--) {
bool last = cradius == endRadius;
bool first = cradius == startRadius && cradius != 0;
float radiusX = cradius;
float radiusY = cradius;
float radiusX2 = radiusX * radiusX;
float radiusY2 = radiusY * radiusY;
float maxTransparency = 127;
float quarter = roundf(radiusX2 / sqrtf(radiusX2 + radiusY2));
for(float _x = 0; _x <= quarter; _x++) {
float _y = radiusY * sqrtf(1 - _x * _x / radiusX2);
float error = _y - floorf(_y);
float transparency = roundf(error * maxTransparency);
int alpha = last ? transparency : maxTransparency;
int alpha2 = first ? maxTransparency - transparency : maxTransparency;
setPixel4(x, y, _x, floorf(_y), r, g, b, alpha, cradius, endRadius, data, areasData, blendColor);
setPixel4(x, y, _x, floorf(_y) - 1, r, g, b, alpha2, cradius, endRadius, data, areasData, blendColor);
}
quarter = roundf(radiusY2 / sqrtf(radiusX2 + radiusY2));
for(float _y = 0; _y <= quarter; _y++) {
float _x = radiusX * sqrtf(1 - _y * _y / radiusY2);
float error = _x - floorf(_x);
float transparency = roundf(error * maxTransparency);
int alpha = last ? transparency : maxTransparency;
int alpha2 = first ? maxTransparency - transparency : maxTransparency;
setPixel4(x, y, floorf(_x), _y, r, g, b, alpha, cradius, endRadius, data, areasData, blendColor);
setPixel4(x, y, floorf(_x) - 1, _y, r, g, b, alpha2, cradius, endRadius, data, areasData, blendColor);
}
}
}
在 setPixel4 中没有调用 drawLine 它看起来像这样:
我改进了 setPixel4 方法以避免再次重绘相同的像素:
void setPixel4(int x, int y, int deltaX, int deltaY, int r, int g, int b, int a, int radius, int maxRadius, unsigned char* data, unsigned char* areasData, bool blendColor) {
for(int j = 0; j < 4; j++) {
int px, py;
if(j == 0) {
px = x + deltaX;
py = y + deltaY;
} else if(j == 1) {
px = x - deltaX;
py = y + deltaY;
} else if(j == 2) {
px = x + deltaX;
py = y - deltaY;
} else if(j == 3) {
px = x - deltaX;
py = y - deltaY;
}
int index = (px + (img->getHeight() - py - 1) * img->getWidth()) * 4;
bool alreadyInBuffer = false;
for(int i = 0; i < dfBufferCounter; i++) {
if(i >= DRAW_FILLED_CIRCLE_BUFFER_SIZE) break;
if(drawFilledCircleBuffer[i] == index) {
alreadyInBuffer = true;
break;
}
}
if(!alreadyInBuffer) {
if(dfBufferCounter < DRAW_FILLED_CIRCLE_BUFFER_SIZE) {
drawFilledCircleBuffer[dfBufferCounter++] = index;
}
setPixelWithCheckingArea(px, py, r, g, b, a, data, areasData, blendColor);
}
}
}
然后,最后:
这几乎是完美的。但是,我花了很多时间来摆脱这个白色轮廓,但我做不到。
最佳答案
因为您将圆圈离散化,所以一些像素必然会丢失。您获得的图片显示了众所周知的莫尔效应。
最好的解决方案是使用任何洪水填充算法或综合在同一水平线(如果您愿意,也可以是垂直线)上的圆点之间画线的简单算法。
关于c++ - Xiaolin Wu 圆算法渲染圆里面有洞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54594822/
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=
我在一个简单的RailsAPI中有以下Controller代码:classApi::V1::AccountsControllerehead:not_foundendendend问题在于,生成的json具有以下格式:{id:2,name:'Simpleaccount',cash_flows:[{id:1,amount:34.3,description:'simpledescription'},{id:2,amount:1.12,description:'otherdescription'}]}我需要我生成的json是camelCase('cashFlows'而不是'cash_flows'