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

Java技术求助:无需math()方法用正方形绘制余弦曲线图案

用正方形绘制平滑余弦曲线的改进方案

你的代码生成方正图案的核心原因是采用了固定的线性阶梯式Y坐标,没有模拟余弦函数的连续平滑变化。要实现自然的余弦曲线,需要基于离散的X采样点计算对应的余弦值,再将其映射为正方形的Y坐标,同时控制X轴的步进密度来提升平滑度。

关键改进点:

  • 放弃固定的分段循环(i/j的5次迭代),改为按X轴步进遍历,每个步进绘制一个正方形
  • 自行实现余弦值的近似计算(不依赖Math类),可以用预定义离散余弦值数组(满足图案绘制的精度需求),或简化的泰勒展开公式
  • 将余弦值(范围-1到1)映射到画布的Y轴范围,确保曲线在可视区域内

修改后的代码示例(预定义余弦值版):

public void zeichne_Cosinus(Graphics g) {
    Zeichenblatt zeichenblatt = new Zeichenblatt(g);
    
    int repetitions = 5;
    int waveLength = 100; // 每个周期的宽度
    int amplitude = 40;   // 曲线振幅(Y方向高度)
    int centerY = 50;     // 曲线中心Y坐标
    int step = 2;         // X轴步进,值越小曲线越平滑

    // 预定义一个周期内的余弦近似值数组(0到2π,采样50个点)
    double[] cosValues = {
        1.0, 0.9808, 0.9239, 0.8315, 0.7071, 0.5556, 0.3827, 0.1951,
        0.0, -0.1951, -0.3827, -0.5556, -0.7071, -0.8315, -0.9239, -0.9808,
        -1.0, -0.9808, -0.9239, -0.8315, -0.7071, -0.5556, -0.3827, -0.1951,
        0.0, 0.1951, 0.3827, 0.5556, 0.7071, 0.8315, 0.9239, 0.9808,
        1.0, 0.9808, 0.9239, 0.8315, 0.7071, 0.5556, 0.3827, 0.1951, 0.0
    };

    for (int rep = 0; rep < repetitions; rep++) {
        int startX = rep * waveLength + 10;
        // 遍历一个周期内的所有采样点
        for (int i = 0; i < cosValues.length; i++) {
            Quadrat quad = new Quadrat();
            // X坐标:起始位置 + 步进*i
            quad.setPositionX(startX + i * step);
            // Y坐标:中心Y + 振幅*余弦值(反向Y轴,适配画布Y向下递增的特性)
            quad.setPositionY(centerY - (int)(amplitude * cosValues[i]));
            // 交替颜色,和原逻辑保持一致
            quad.setFarbe(i % 2 == 0 ? Color.orange : Color.green);
            
            zeichenblatt.zeichne(quad);
        }
    }
}

代码说明:

  1. 预定义余弦数组:避免依赖Math.cos,直接用预先计算的近似值,精度足够满足图案绘制需求
  2. 坐标映射:通过centerY - amplitude*cosValue将余弦值(-1到1)转换为画布的Y坐标,适配画布Y轴向下递增的特性
  3. 平滑度控制:step变量控制X轴的步进大小,值越小,每个周期内的正方形越多,曲线越平滑
  4. 多周期重复:通过repetitions控制绘制的余弦曲线周期数,和原逻辑保持一致

如果需要动态计算余弦值(不用预定义数组),可以实现简化的泰勒展开(前3项足够近似):

// 计算x(弧度)的余弦近似值,x范围0到2π
private double approximateCos(double x) {
    // 泰勒展开简化版:cos(x) ≈ 1 - x²/2! + x⁴/4!
    double xSquared = x * x;
    double xFourth = xSquared * xSquared;
    return 1 - xSquared / 2 + xFourth / 24;
}

使用时,将循环改为遍历0到2π的弧度值:

for (int rep = 0; rep < repetitions; rep++) {
    int startX = rep * waveLength + 10;
    for (int i = 0; i < waveLength; i += step) {
        // 用3.1415926代替Math.PI,避免依赖Math类
        double radian = (double)i / waveLength * 2 * 3.1415926;
        double cosVal = approximateCos(radian);
        
        Quadrat quad = new Quadrat();
        quad.setPositionX(startX + i);
        quad.setPositionY(centerY - (int)(amplitude * cosVal));
        quad.setFarbe(i % 2 == 0 ? Color.orange : Color.green);
        
        zeichenblatt.zeichne(quad);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 06:32:34