简体   繁体   English

使用Canvas Logic在三角形中获得180度

[英]Getting 180 Degree in a Triangle using Canvas Logic

I am trying to create a small program where all degrees in a triangle will add up to 180 degrees. 我正在尝试创建一个小程序,将三角形中的所有度数加起来为180度。 So far what I have is that when I use the Math.Random method, I get a random number but somethings the degrees do not add up to 180°. 到目前为止,我所拥有的是,当我使用Math.Random方法时,我得到了一个随机数,但是有些东西的角度加起来不等于180°。 I have tried using the if condition statement but no luck so far. 我已经尝试过使用if条件语句,但到目前为止还没有运气。

Here is my code: 这是我的代码:

https://jsfiddle.net/14p880p9/ 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);

Use this, it can generate ANY combination, unlike the limited above option where one of the sides must be 1-100. 使用此选项,它可以生成ANY组合,这与上述有限的选项不同,其中边之一必须为1-100。

var a = Math.round((Math.random() * 90) + 1);
var b = Math.round((Math.random() * 90) + 1);
var c = 180 - a - b;

Your logic for the generation of the randomness is a little off. 您生成随机性的逻辑有些偏离。 At the minute you're asking it to generate 3 random numbers between 1-100. 在一分钟,您要求它生成1-100之间的3个随机数。 The downside to this approach is the numbers have no bearing on having to add to 180; 这种方法的缺点是数字与必须增加到180没有关系。

You should update this logic to know that the total must equal 180. Something like this: 您应该更新此逻辑,以知道总数必须等于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 JSFIDDLE

a) either use a stick... a)用棍子...

An easy way to tackle this is to visualize your 180 as a stick. 解决此问题的一种简单方法是将您的180杆可视化。 You want to break that stick into 3 pieces. 您想把棍子分成三块。 So all you need to do is generate two non-equal rounded random values from 1 to 179 (the cutting points: one & two ). 因此,您所需要做的就是生成两个从1到179的非等值舍入随机值(切入点: onetwo )。 And your random values will be: 您的随机值将是:

  • a : from zero to smallest value cutting point a :从零到最小值的切割点
  • b : from smallest to largest value cutting points b :从最小到最大切割点
  • c : from largest value cutting point to 180 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 = ta + ' + ' + tb + ' + ' + tc + ' = ' + (ta + tb + tc); document.getElementsByTagName('body')[0].appendChild(div); } 
 div { width: 33.3333%; float: left; padding: .5rem 0; text-align: center; } 


b) ... or maths b)...或数学

While the above method is easy to visualize, and ensures each segment value has equal chances at being anywhere between 1 and 178 ( total - ( parts - 1 )), it's not particularly efficient from a programming point of view. 虽然上面的方法很容易可视化,并且确保每个段值在1178之间( total -( parts -1))的机会均等,但从编程角度来看并不是特别有效。

Each time one of the cutting points overlaps an existing one, it needs to be recalculated. 切割点之一每次与现有切割点重叠时,都需要重新计算。 In our case that would be quite rare but, given variable values for total and parts , the odds of it happening might differ. 在我们的情况下,这是非常罕见的,但是,如果给定totalparts变量值,则发生这种情况的几率可能会有所不同。
Besides, we can totally avoid having to regenerate any value, thus saving computing power and, ultimately, the planet, or at least delaying its doom by an insignificant amount of time. 此外,我们完全可以避免重新生成任何值,从而节省了计算能力,并最终节省了地球,或者至少将其厄运延迟了很短的时间。

If we look at this from a mathematical point of view, we'll notice 如果我们从数学的角度来看这个,我们会注意到

  • at least 1 part will be smaller than 61 ((180 / (3 - 0)) + 1) 至少1部分小于61 ((180 / (3 - 0)) + 1)
  • at least 2 parts will be smaller than 91 ((180 / (3 - 1)) + 1) 至少2部分小于91 ((180 / (3 - 1)) + 1)

So, as a general rule, at least n parts will be smaller than (total / (parts - (n - 1)) + 1) . 因此,通常,至少n部分将小于(total / (parts - (n - 1)) + 1) Now let's rewrite our method, generating the minimal amount or random numbers, in the correct range of possible values. 现在,让我们重写我们的方法,在可能的值的正确范围内生成最小数量或随机数。
We also need to add as a last value the difference between total and the sum of all previous values. 我们还需要之间添加作为最后的值之差total与所有先前值的总和。
To make it more useful, I also considered total and parts as variables, so the method could be used to segment any total number into any number of parts . 为了使其更有用,我还将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; } 

Using this method, the first entry in the array has the biggest chances of having the smallest value while the last part has the biggest chances of having the highest value. 使用此方法,数组中的第一个条目具有最小值的可能性最大,而最后一部分具有最大值的可能性最大。

Note: Using this in a production environment is not recommended without sanitizing the input values. 注意: 建议在不清除输入值的情况下在生产环境中使用它。

Another note: To calculate the sum of all existing values in an array I used this awesome answer 's method. 另一个注意事项:为了计算数组中所有现有值的总和,我使用了这个awesome answer方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM