You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于函数值在Openframeworks中绘制不同颜色及大小的圆形

嘿,你已经搞定了JSON读取和基础绘制这两步,接下来调整圆形的颜色和大小其实核心就是把你的函数值映射到OpenFrameworks能直接用的视觉参数范围,我给你一步步拆解具体方案:

核心工具:ofMap() 数据映射

你的函数值大概率是自定义范围(比如0-1000、-50到50),但画布尺寸、颜色分量都是固定范围(比如半径5-50像素,颜色RGB值0-255),OpenFrameworks的ofMap()就是专门干这个转换的,能帮你把任意范围的数值线性映射到目标区间,还能自动限制超出范围的值。


一、根据函数值调整圆形大小

假设你从JSON里拿到的单个函数值存在float funcValue变量里,先确定这个值的全局最小/最大值(可以从所有JSON数据里统计,或者预先设定),然后映射到你想要的半径范围:

// 示例:把funcValue从[minVal, maxVal]映射到[5, 50]的半径范围
// 最后一个true开启clamp,避免极端值导致半径异常
float radius = ofMap(funcValue, minVal, maxVal, 5, 50, true);

之后画圆时直接用这个radius即可:ofDrawCircle(x, y, radius);


二、根据函数值调整圆形颜色

这里给你三种常用的颜色映射方案,按需选择:

1. 灰度映射(简单直接)

把函数值直接转换成0-255的灰度值:

float gray = ofMap(funcValue, minVal, maxVal, 0, 255, true);
ofSetColor(gray); // 等价于ofSetColor(gray, gray, gray)

2. 双色渐变(视觉层次丰富)

定义两个极端颜色,根据函数值比例做线性插值,比如从蓝色过渡到红色:

// 先定义两个基准颜色:最小值对应浅蓝,最大值对应浅红
ofColor colorMin = ofColor(0, 128, 255);
ofColor colorMax = ofColor(255, 64, 64);
// 把函数值映射到0-1的比例值
float colorRatio = ofMap(funcValue, minVal, maxVal, 0.0f, 1.0f, true);
// 线性插值得到最终颜色
ofColor currentColor = colorMin.getLerped(colorMax, colorRatio);
ofSetColor(currentColor);

3. 自定义分段颜色(规则明确)

如果需要按阈值区分颜色(比如低数值绿、中数值黄、高数值红),直接用条件判断:

if(funcValue < 20){
    ofSetColor(0, 255, 0); // 绿色
}else if(funcValue < 60){
    ofSetColor(255, 255, 0); // 黄色
}else{
    ofSetColor(255, 0, 0); // 红色
}

完整整合示例代码

假设你已经把JSON里的函数值和对应坐标分别存在vector<float> funcValues和vector<ofVec2f> positions里,完整代码如下:

ofApp.h 声明变量

class ofApp : public ofBaseApp{
public:
    void setup();
    void update();
    void draw();

    vector<float> funcValues;
    vector<ofVec2f> positions;
    float minVal, maxVal; // 函数值的全局最小/最大值
};

ofApp.cpp 实现逻辑

//--------------------------------------------------------------
void ofApp::setup(){
    // 这里假设你已经完成JSON读取,把数据存入funcValues和positions
    // 统计函数值的最小/最大值(动态数据建议每次刷新后重新计算)
    minVal = *min_element(funcValues.begin(), funcValues.end());
    maxVal = *max_element(funcValues.begin(), funcValues.end());
}

//--------------------------------------------------------------
void ofApp::update(){

}

//--------------------------------------------------------------
void ofApp::draw(){
    ofBackground(255); // 白色背景
    
    for(int i=0; i<funcValues.size(); i++){
        float val = funcValues[i];
        ofVec2f pos = positions[i];
        
        // 计算半径
        float radius = ofMap(val, minVal, maxVal, 5, 50, true);
        
        // 计算渐变颜色
        ofColor colorMin = ofColor(0, 128, 255);
        ofColor colorMax = ofColor(255, 64, 64);
        float ratio = ofMap(val, minVal, maxVal, 0.0f, 1.0f, true);
        ofColor currentCol = colorMin.getLerped(colorMax, ratio);
        
        // 绘制圆形
        ofSetColor(currentCol);
        ofDrawCircle(pos.x, pos.y, radius);
    }
}

额外小提示

  • 如果JSON数据是实时更新的,记得在数据刷新时重新计算minVal和maxVal,避免映射失效
  • 想要非线性的大小/颜色变化?可以给ofMap()的结果套个数学函数,比如float radius = 5 + pow(ofMap(val, minVal, maxVal, 0, 1, true), 2) * 45;,让小值的半径变化更平缓,大值变化更明显
  • 试试ofNoFill()画空心圆,配合ofSetLineWidth()调整线条粗细,能实现完全不同的视觉效果

内容的提问来源于stack exchange,提问作者Akira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:10:30