我正在尝试创建一个小程序,将三角形中的所有度数加起来为180度。到目前为止,我所拥有的是,当我使用Math.Random方法时,我得到了一个随机数,但某些东西的度数之和不等于180°。我已经尝试过使用if条件语句,但到目前为止还没有运气。

这是我的代码:

https://jsfiddle.net/14p880p9/

    var a = Math.round((Math.random() * 100) + 1);
    var b = Math.round((Math.random() * 100) + 1);
    var c = Math.round((Math.random() * 100) + 1);

    var d = a + b + c;



    ctx.beginPath();
    ctx.moveTo(50, 10);
    ctx.lineTo(50, 450);
    ctx.lineTo(650, 400);
    ctx.closePath();
    ctx.lineWidth = 10;
    ctx.strokeStyle = '#666666';
    ctx.stroke();
    ctx.fillStyle = "#FFCC00";
    ctx.fill();

    ctx.font = "30px Comic Sans MS";
    ctx.fillStyle = "black";
    ctx.fillText(a + "°",52,60);


    //width distance, and then altitude
    ctx.font = "30px Comic Sans MS";
    ctx.fillStyle = "black";
    ctx.fillText(b+ "°",60,420);



    //width distance, and then altitude
    ctx.font = "30px Comic Sans MS";
    ctx.fillStyle = "black";
    ctx.fillText(c + "°",570,400);

最佳答案

a)用棍子...

解决此问题的一种简单方法是将您的180可视化为棍子。您想把棍子分成三块。因此,您要做的就是生成两个从1到179的非等值舍入随机值(切点:onetwo)。您的随机值将是:


a:从零到最小值切割点
b:从最小到最大切割点
c:从最大值切割点到180




var Triangle = function() {
    this.getRandom = function() {
        // 1 - 179 random integer generator
        return Math.round(Math.random() * (179 - 1) + 1);
    }

    this.one = this.getRandom();
    this.two = this.getRandom();

    while (this.one == this.two) {
        // if equal, regenerate second - we don't want any segment to have 0 length
        this.two = this.getRandom();
    }

    return {
        'a': Math.min(this.one, this.two),
        'b': Math.max(this.one, this.two) - Math.min(this.one, this.two),
        'c': 180 - Math.max(this.one, this.two)
    }
}

// Now let's make a few tests... how about 180 tests?
for (var i = 0; i < 180; i++) {

    var t = new Triangle;

    var div = document.createElement('div');
    div.innerHTML = t.a + ' + ' + t.b + ' + ' + t.c + ' = ' +
        (t.a + t.b + t.c);

    document.getElementsByTagName('body')[0].appendChild(div);
}

div {
  width: 33.3333%;
  float: left;
  padding: .5rem 0;
  text-align: center;
}







b)...或数学

虽然上面的方法很容易可视化,并且确保每个段值在1178total-(parts-1))之间的机会均等,但是从编程角度来看并不是特别有效观点。

切割点之一每次与现有切割点重叠时,都需要重新计算。在我们的情况下,这种情况很少见,但是,给定totalparts的变量值,发生这种情况的几率可能会有所不同。
此外,我们完全可以避免重新生成任何值,从而节省了计算能力,并最终节省了地球,或者至少将其厄运延迟了很短的时间。

如果我们从数学的角度来看这个,我们会注意到


至少1部分将小于61 ((180 / (3 - 0)) + 1)
至少2个部分将小于91 ((180 / (3 - 1)) + 1)


因此,通常,至少n个部分将小于(total / (parts - (n - 1)) + 1)。现在,让我们重写我们的方法,在可能的值的正确范围内生成最小数量或随机数。
我们还需要将total与所有先前值的总和之差作为最后一个值。
为了使其更有用,我还考虑了totalparts作为变量,因此该方法可用于将任何total数字分割为任意数量的parts



var Segmentation = function (total, parts) {
    this.random = function (min, max) {
        return Math.round(Math.random() * (max - min) + min);
    }

    this.segments = [];
    for (var i = 0; i < parts - 1; i++) {
        this.segments.push(this.random(parts - i, total / parts + 1));
    }

    this.segments.push(total - this.segments.reduce((a, b) => a + b, 0));
    return this.segments;

}
// let's test it

var h1 = document.createElement('h2');
h1.innerHTML = 'Triangles';
document.getElementsByTagName('body')[0].appendChild(h1);

for (var i = 0; i < 21; i++) {

    var t = new Segmentation(180, 3),
        div = document.createElement('div');

    div.innerHTML = '';
    for (var j = 0; j < t.length; j++) {
        div.innerHTML += t[j] + (t.length - j > 1 ? ' + ' : ' = ');
    }
    div.innerHTML += t.reduce((a, b) => a + b, 0);

    document.getElementsByTagName('body')[0].appendChild(div);
}

var h1 = document.createElement('h2');
h1.innerHTML = '<hr />Rectangles';
document.getElementsByTagName('body')[0].appendChild(h1);

for (var i = 0; i < 21; i++) {

    var t = new Segmentation(360, 4),
        div = document.createElement('div');

    div.innerHTML = '';
    for (var j = 0; j < t.length; j++) {
        div.innerHTML += t[j] + (t.length - j > 1 ? ' + ' : ' = ');
    }
    div.innerHTML += t.reduce((a, b) => a + b, 0);

    document.getElementsByTagName('body')[0].appendChild(div);
}

var h1 = document.createElement('h2');
h1.innerHTML = '<hr />Random segments';
document.getElementsByTagName('body')[0].appendChild(h1);

for (var i = 0; i < 21; i++) {
    var total = Math.round(Math.random() * (2000 - 200) + 200),
        parts = Math.round(Math.random() * (8 - 3) + 3),
        t = new Segmentation(total, parts);

    var div = document.createElement('div');
    div.className = ('full');
    div.innerHTML = '';
    for (var j = 0; j < t.length; j++) {
        div.innerHTML += t[j] + (t.length - j > 1 ? ' + ' : ' = ');
    }
    div.innerHTML += t.reduce((a, b) => a + b, 0);

    document.getElementsByTagName('body')[0].appendChild(div);
}

div {
  width: 33.3333%;
  float: left;
  padding: .5rem 0;
  text-align: center;
}

div.full {
  width: 100%;
  text-align: initial;
}





使用此方法,数组中的第一个条目具有最小值的最大机会,而最后一个部分具有最大值的最大机会。

注意:不建议在不清除输入值的情况下在生产环境中使用它。

另一个注意事项:为了计算数组中所有现有值的总和,我使用了此awesome answer的方法。

关于javascript - 使用Canvas Logic在三 Angular 形中获得180度,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42405581/

10-13 01:37