- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在我的一个项目中(VC++2010,MFC),我想用CDC::Ellipse画一个圆。我设置了两个点:第一个是圆心,第二个是我希望它在圆周上的一个点。
我将左上角和右下角的坐标传递给 CDC::Ellipse( int x1, int y1, int x2, int y2 )。
简而言之:我使用 Pitagora 定理计算两点之间的距离(半径),然后我从中心的坐标中减去该值以获得左上角并添加以获得右下角。
当我绘制圆和点并放大时,我看到第二个并不像预期的那样在圆周上,它稍微在里面,除非你将它设置为 0°、45°、90° 和以此类推关于坐标的绝对系统。
然后我尝试使用 CDC::Polyline 绘制相同的圆,我将获得的点赋予该方法,该点围绕中心旋转另一个点,距离等于半径。在这种情况下,该点位于我设置的每个圆周上。
这两个圆的重叠表明它们在 0°、45°、90° 等处完全重叠,但在 22.5°、67.5° 等处差距最大。
有没有人注意到类似的行为?
感谢所有能帮助我的人!
代码片段:
这就是我如何计算给定 2 个点的半径:
centerPX = vvFPoint( 1380, 845 );
secondPointPX = vvFPoint( 654,654 );
double radiusPX = (sqrt( (secondPointPX.x - centerPX.x) * (secondPointPX.x - centerPX.x) + (secondPointPX.y - centerPX.y) * (secondPointPX.y - centerPX.y) ));
(vvFPoint 是从 CPoint 派生的自定义类型)
这就是我使用 CDC::Ellipse 绘制“圆”的方式:
int up = (int)(((double)(m_p1.y-(double)originY - m_radius) / zoom) + 0.5) + offY;
int left = (int)(((double)(m_p1.x-(double)originX - m_radius) / zoom) + 0.5) + offX;
int down = (int)(((double)(m_p1.y-(double)originY + m_radius) / zoom) + 0.5) + offY;
int right = (int)(((double)(m_p1.x-(double)originX + m_radius) / zoom) + 0.5) + offX;
pDC->Ellipse( left, up, right, down);
(m_p1为圆心,originX/Y为图像原点,m_radius为圆半径, zoom 是比例因子, offX/Y 是我软件客户区的偏移)
这就是我使用自定义多段线类“手动”绘制圆(以及非常简单的方法)的方式:
1) 创建点数组:
point.x = centerPX.x + radiusPX;
point.y = centerPX.y;
for ( i=0; i < 3600; i++ )
{
pt1.RotateDeg ( centerPX, (double)0.1 );
poly->AddPoint( pt1 );
}
(RotateDeg 是一种自定义方法,使用第一个参数作为枢轴,第二个参数作为以度为单位的角度值来旋转点,AddPoint 是一种自定义方法来创建点数组,poly 是我的自定义折线对象)。
2) 绘制它:
当我调用 Draw( CDC* pDC ) 时,我使用之前的数组绘制折线:
pDC->MoveTo(p);
我希望这可以帮助您重现我奇怪的观察结果!
代码片段 2:
void vvPoint<Tipo>::RotateDeg(const vvPoint<Tipo> ¢er, double angle)
{
vvPoint<Tipo> ptB;
angle *= -(M_PI / 180);
*this -= center;
ptB.x = ((this->x * cos(angle)) - (this->y * sin(angle)));
ptB.y = ((this->x * sin(angle)) + (this->y * cos(angle)));
*this = ptB + center;
}
但为了让您更好地理解我的观察结果,我想添加一些图片,以便您可以看到我的整个问题是从哪里开始的……问题是:我无法添加图片,因为我需要有 10 个声誉。我在保管箱上上传了一个 .zip 文件,如果您需要,我可以将此文件的 URL 发送给您。让我知道这是否是绕过此问题的正确(和安全..)方法。
谢谢!
最佳答案
这可能是一个可能的解释。作为MSDN says关于 CDC::Ellipse
(我强调):
The center of the ellipse is the center of the bounding rectangle specified by x1, y1, x2, and y2, or lpRect. The ellipse is drawn with the current pen, and its interior is filled with the current brush.
The figure drawn by this function extends up to, but does not include, the right and bottom coordinates. This means that the height of the figure is y2 – y1 and the width of the figure is x2 – x1.
您描述的如何计算边界矩形的方式并不完全清楚(一些源代码会有所帮助)但是,鉴于上面引用的第二段,您可能需要将 1 添加到您的 x2和 y2 值,以确保您有一个具有所需半径的圆。
还值得注意的是,您的两种绘图方法之间可能存在细微的舍入差异,其中您的边界框大小不正确(即中心点逻辑上落在半像素上)。
更新
使用您的代码片段(谢谢),并假设没有缩放和零偏移等,我得到了 750.704 像素的半径和以下椭圆参数:
pDC->Ellipse(629, 94, 2131, 1596);
根据MSDN,这意味着椭圆将绘制成如下尺寸的图形:
width = (2131 - 629) = 1502
height = (1596 - 94) = 1502
据我所知,这应该产生一个圆而不是椭圆。
接下来要做的是弄清楚您是如何绘制多边形的 - 为此我们需要查看 RotateDeg
的实现 - 您可以发布该代码吗?我怀疑这里有一些简单的舍入误差,当你缩放时它可能会被放大。
更新 2
只看这段代码:
for ( i=0; i < 3600; i++ )
{
pt1.RotateDeg ( centerPX, (double)0.1 );
poly->AddPoint( pt1 );
}
您每次以 0.1 度的增量旋转多边形点。这可能会累积一些错误,因此可能值得这样做:
for ( i=0; i < 3600; i++ )
{
vvFPoint ptNew = pt1;
ptNew.RotateDeg ( centerPX, (double)i * 0.1 );
poly->AddPoint( ptNew );
}
也许这意味着您必须更改 RotateDeg
函数以处理正确的象限。
还有一点,您提到在放大图像时会看到问题。如果这意味着您正在使用 zoom
变量,则值得检查这一行 ...:
pDC->Ellipse( left, up, right, down);
...参数仍然形成正方形,所以 (right - left) == (down - up)
。
更新 3
我刚刚以当前形式运行了您的 RotateDeg
函数,以查看错误是如何累积的(通过将上一个结果输入下一个迭代)。在每一步中,我都会计算新点与中心之间的距离,并将其与所需的半径进行比较。
下图显示了结果,在计算点时您可以看到 4 个像素的误差。
我认为这至少解释了部分差异(即你的多边形绘图有缺陷)并且 - 根据 zoom
- 你可能会在椭圆参数中引入不对称性,你可以通过比较来调试如上所述的宽度到高度。
关于c++ - CDC::Ellipse 不能正确绘制圆圈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19703907/
我是 javascript 的新手(今天开始弄乱它)。 我正在尝试更改名为“bar”的元素(div)的高度。条形图将成为图表的一部分。 我可以毫无问题地将按钮连接到更改栏高度的函数。一切正常,除了条形
错误 -> “UIVIew”没有名为“addSubView”的成员 override func viewDidLoad() { super.viewDidLoad() // Do an
我在命令行工具项目中复制并粘贴了 main.swift 下面链接中的代码。 How do you use CGEventTapCreate in Swift? 它构建没有错误,但是当我运行时, gua
我在尝试编译我的代码时遇到以下错误。 ERROR! ..\myCode\CPOI.cpp:68:41: error: cannot dynamic_cast 'screenType' (of type
我正在尝试将多个字符串连接到一个我已为其分配内存的字符串指针。这是一个例子: char *finalNumString = malloc(sizeof(char)*1024); finalNumStr
我在使用 dup2() 和 pipe() 时遇到问题。 当我尝试将管道的写入端 dup2 到 STDOUT_FILENO 时,我收到了 EBADF。 我用 gdb 在 dup2(pout[1], ST
首先,我应该说我运行的是 Windows 7。 因此,今天早上我尝试像往常一样从我的存储库中提取数据,但我做不到。我得到了错误: The authenticity of host 'github.co
刚开始在虚拟环境中运行Python,乱用Django,无法激活虚拟环境。 花了最后 4 个小时尝试在本地终端/VS 代码上激活虚拟环境 (venv),但没有成功。 避免使用“sudo pip inst
Tidyverse 的粉丝经常给出使用小标题而不是数据框的几个优点。它们中的大多数似乎旨在保护用户免于犯错误。例如,与数据框不同,小标题: 不需要 ,drop=FALSE不从数据中删除维度的论据。 不
我一直在对 Elm 应用程序进行 docker 化时遇到问题。据我所知,我已经创建了一个完整且有效的 Docker 文件……但它不起作用。 我会解释的。 所以我的脚本在 3 个文件中运行。 首先是启动
我可以在 Controller 中使用@Autowired,例如 @RestController public class Index { @Autowired HttpServlet
我定义了一个方法和一个函数: def print(str:String) = println val intToString = (n:Int) => n.toString 现在我想创作它们。 我的问
当我控制台单独记录变量“pokemons”时,它确实返回一个数组。但是当我尝试映射它时,出现错误: TypeError: pokemons.map is not a function 我的代码: im
每当我尝试在 Python 解释器中导入 smtplib 时,都会收到此错误: ImportError: cannot import name fix_eols 我该如何解决这个问题? 编辑:这是完整
我正在使用 Meteor.js 开发一个项目,但在使用 Handlebar 时遇到了一些问题:我想检索集合的最后一项,并显示字段:其中包含 html 的文本: 这是我的javascript代码: Te
你好,我想使用 Service 实现 GestureDetector 但是我有这个错误The method onTouchEvent(MotionEvent) of type GestureServi
我正在尝试在 Controller bean 中 Autowiring 接口(interface) 在我放置的上下文配置文件中 和 我的 Controller 类是 @Controller pub
我试图在 mainwindow.cpp 中包含 QtSvg,但是当我编译时它说无法打开包含文件:QtSvg。我已经在我的 *.pro 文件中添加了这个(QT += svg)。我可以知道可能是什么问题吗
鉴于以下 PostgreSQL 代码,我认为这段代码不容易受到 SQL 注入(inject)攻击: _filter 'day' _start 1 _end 10 _sort 'article_name
我想执行以下操作。这在 MySQL 中是非法的。 PostGRESQL 中关联的 CTE(“with”子句)有效。这里的假设是 MySQL 中的子查询不是完全限定的 CTE。 请注意:这个查询显然非常
我是一名优秀的程序员,十分优秀!