我正在尝试创建一个小程序,其中三角形中的所有度数将加起来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);
答案 0 :(得分:3)
使用它,它可以生成任何组合,不像上面有限的选项,其中一个边必须是1-100。
createMarker
答案 1 :(得分:1)
您生成随机性的逻辑有点偏差。在你要求它在1-100之间产生3个随机数的那一刻。这种方法的缺点是数字与必须添加到180无关;
你应该更新这个逻辑,知道总数必须等于180.这样的事情:
var a = Math.round((Math.random() * 100) + 1); // generates a random number between 1-100
var b = Math.round((Math.random() * (179-a)) + 1); // generates a random number between 1-179 (minus a)
var c = 180 - a - b; // is the remaining value of 180 - a - b
var d = a + b + c;
<强> JSFIDDLE 强>
答案 2 :(得分:1)
a)要么用棍子......
解决此问题的一种简单方法是将180
视为一根棍子。你想把那根棍子分成3块。因此,您需要做的就是生成两个不等的舍入随机值,从1到179(切割点:one
&amp; two
)。你的随机值将是:
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)......或数学
虽然上述方法很容易可视化,但确保每个细分值在1
和178
之间的任何位置都有相同的机会(total
- (parts
- 1 )),从编程的角度来看,它并不是特别有效。
每次其中一个切割点与现有切割点重叠时,需要重新计算。在我们的情况下,这是非常罕见的,但鉴于total
和parts
的变量值,它发生的几率可能不同。
此外,我们完全可以避免重新生成任何价值,从而节省计算能力,最终节省地球,或者至少在很短的时间内推迟它的厄运。
如果我们从数学的角度来看这个,我们会注意到
1
部分将小于61
((180 / (3 - 0)) + 1)
2
部分将小于91
((180 / (3 - 1)) + 1)
因此,作为一般规则,至少n
部分将小于(total / (parts - (n - 1)) + 1)
。现在让我们重写我们的方法,在正确的可能值范围内生成最小量或随机数
我们还需要将total
与之前所有值的总和之间的差值作为最后一个值添加
为了使其更有用,我还将total
和parts
视为变量,因此该方法可用于将任何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
的方法。