用距离

时间:2016-01-16 13:40:00

标签: math

我有一个比编程问题更多的数学问题,对不起,如果我不在正确的部分。在我的2D游戏中,我们可以将相机移动到可以发出声音的物体的地图上,当屏幕中心靠近此物体时,此音量(由0到1的浮点定义)必须增加。例如,当对象位于屏幕中心时,音量为1,当我们离开时,音量必须减小。每个对象都有自己的范围值。 (例如1000像素)。

我不知道如何编写可以计算它的方法。 这是我的一些代码(这不是正确的计算):

private function setVolumeWithDistance():Void
{
    sound.volume = getDistanceFromScreenCenter() / range;
    // So the volume is a 0 to 1 float, the range is the scope in pixels and 
    // and the getDistanceFromScreenCenter() is the distance in pixels
}  

我已经有了计算物体距中心屏幕的距离的方法:

public function getDistanceFromScreenCenter():Float
{
    return Math.sqrt(Math.pow((Cameraman.getInstance().getFocusPosition().x - position.x), 2) +
                     Math.pow((Cameraman.getInstance().getFocusPosition().y - position.y), 2));

1 个答案:

答案 0 :(得分:1)

简单的声学可以提供帮助。

Here是来自点源的声强公式。它遵循距离规则的反平方。将其构建到您的代码中。

您需要考虑全局和屏幕坐标之间的映射。您必须将屏幕上的像素位置映射到物理坐标并返回。

您的距离代码存在缺陷。没有人应该使用pow()来对数字进行平方。你很容易出现舍入错误。

此代码结合距离计算,正确完成,并尝试解决逆平方强度计算。注意:对于零距离,反平方是奇异的。

package physics;

/**
 * Simple model for an acoustic point source
 * Created by Michael
 * Creation date 1/16/2016.
 * @link https://stackoverflow.com/questions/34827629/calculate-sound-value-with-distance/34828300?noredirect=1#comment57399595_34828300
 */
public class AcousticPointSource {

    // Units matter here....
    private static final double DEFAULT_REFERENCE_INTENSITY = 0.01;
    private static final double DEFAULT_REFERENCE_DISTANCE = 1.0;

    // Units matter here...
    private double referenceDistance;
    private double referenceIntensity;

    public static void main(String[] args) {
        int numPoints = 20;
        double x = 0.0;
        double dx = 0.05;
        AcousticPointSource source = new AcousticPointSource();
        for (int i = 0; i < numPoints; ++i) {
            x += dx;
            Point p = new Point(x);
            System.out.println(String.format("point %s intensity %-10.6f", p, source.intensity(p)));
        }
    }

    public AcousticPointSource() {
        this(DEFAULT_REFERENCE_DISTANCE, DEFAULT_REFERENCE_INTENSITY);
    }

    public AcousticPointSource(double referenceDistance, double referenceIntensity) {
        if (referenceDistance <= 0.0) throw new IllegalArgumentException("distance must be positive");
        if (referenceIntensity <= 0.0) throw new IllegalArgumentException("intensity must be positive");
        this.referenceDistance = referenceDistance;
        this.referenceIntensity = referenceIntensity;
    }

    public double distance2D(Point p1) {
        return distance2D(p1, Point.ZERO);
    }

    public double distance2D(Point p1, Point p2) {
        double distance = 0.0;
        if ((p1 != null) && (p2 != null)) {
            double dx = Math.abs(p1.x - p2.x);
            double dy = Math.abs(p1.y - p2.y);
            double ratio;
            if (dx > dy) {
                ratio = dy/dx;
                distance = dx;
            } else {
                ratio = dx/dy;
                distance = dy;
            }
            distance *= Math.sqrt(1.0 + ratio*ratio);
            if (Double.isNaN(distance)) {
                distance = 0.0;
            }
        }
        return distance;
    }

    public double intensity(Point p) {
        double intensity = 0.0;
        if (p != null) {
            double distance = distance2D(p);
            if (distance != 0.0) {
                double ratio = this.referenceDistance/distance;
                intensity = this.referenceIntensity*ratio*ratio;
            }
        }
        return intensity;
    }
}

class Point {

    public static final Point ZERO = new Point(0.0, 0.0, 0.0);

    public final double x;
    public final double y;
    public final double z;

    public Point(double x) {
        this(x, 0.0, 0.0);
    }

    public Point(double x, double y) {
        this(x, y, 0.0);
    }
    public Point(double x, double y, double z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    @Override
    public String toString() {
        return String.format("(%-10.4f,%-10.4f,%-10.4f)", x, y, z);
    }
}