首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对某些RGB值给出NaN的RGB

对某些RGB值给出NaN的RGB
EN

Stack Overflow用户
提问于 2020-02-20 06:31:09
回答 1查看 135关注 0票数 0

我有一个函数来计算给定rgb值的色调。对于某些值,acos返回NaN,因为参数略大于1。这段代码遵循了我在网上找到的大多数公式,但我不知道为什么会弹出NaN。

例子有:

代码语言:javascript
复制
40 28 28
40 28 28
40 28 28
49 25 25
46 34 34
40 28 28
42 24 24
42 24 24
40 22 22
40 22 22
代码语言:javascript
复制
#include <math.h>

double hue(unsigned char r, unsigned char g, unsigned char b) {
  double rn = (double) r / (r + g + b);
  double gn = (double) g / (r + g + b);
  double bn = (double) b / (r + g + b);

  if (rn == gn && gn == bn) {
    return 0;
  }

  double h = acos((rn - gn + rn - bn) / (2.0 * sqrt((rn - gn) * (rn - gn) + (rn - bn) * (gn - bn))));

  // issue with the argument of acos being just slightly bigger than 1. Approximate to 0
  if (isnan(h)) {
    h = 0;
  }

  if (b > g) {
    return (2 * M_PI - h) * (180.0 / M_PI);
  } else {
    return h * (180.0 / M_PI);
  }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-20 09:17:16

我不知道为什么NaN会突然出现

答案就在你的问题中:

,因为参数略大于1

在这种情况下,正确的问题是:

如何确保acos的参数不大于1?

为此,您需要分析您的公式,并查看问题的来源。sqrt和该部门有可能发挥作用。

最简单的攻击(可能对应用程序不利)是首先验证参数是否大于1,如果是,则将其截断为1。

请注意,您丢失了计算rngnbn的额外精度。最好将sqrt的参数计算为:

代码语言:javascript
复制
a = (r-g)*(r-g)+(r-b)*(g-b);
b = (r+g+b)*(r+g+b);
argument = a/b;

玩它,看看会发生什么。

另外,序列

代码语言:javascript
复制
// issue with the argument of acos being just slightly bigger than 1. Approximate to 0
if (isnan(h)) {
    h = 0;
}

应该在调用acos之前使用,并使用acos的(预计算)参数,而不是计算的h

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60314086

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档