2014-10-27 56 views
8

我正在寻找一种聪明的方式来递增,然后递减计数器变量。我希望计数器变量从低值开始增加,并向更高值增加。一旦达到较高值,计数器将递减,直到达到较低值。一旦达到较低的值,计数器再次增加到更高的值......我想你明白了。我们如何增加然后递减没有条件的计数器?

我工作的AA canvas animation,我想使用一些小聪明,而无需使用if或其他条件测试:

这里是处理计数器变量的条件逻辑:

incrementing = true 

foo = -> 

    length += 1 if incrementing 
    length -= 1 if not incrementing 

    incrementing = false if length > 100 
    incrementing = true if length < 1 

最初,我想我可以使用模数。但是,模除法只会将计数器重置为较低的值 - 一旦计数器达到最高值,它不会使计数器递减。

0 % 10 = 0 
1 % 10 = 1 
2 % 10 = 2 
3 % 10 = 3 
4 % 10 = 4 
5 % 10 = 5 
6 % 10 = 6 
7 % 10 = 7 
8 % 10 = 8 
9 % 10 = 9 
10 % 10 = 0 
11 % 10 = 1 
12 % 10 = 2 
13 % 10 = 3 

我确定必须有一种方法来做到这一点,而不使用条件测试。假设底部值为0,顶部值为10,则该方法应输出以下内容。

? = 0 
? = 1 
? = 2 
? = 3 
? = 4 
? = 5 
? = 6 
? = 7 
? = 8 
? = 9 
? = 8 
? = 7 
? = 6 
? = 5 
+1

'+ 1'需要一个完全没有问题的解决方案,纯粹是为了让你的代码更漂亮。这就是我们学习CoffeeScript的原因。 – 2014-10-29 15:42:52

回答

15

首先让我们看看一些波!

你好!

types of waves

你能找出符合你的需求吗?

如果你猜对了Triangle Wave,你是对的!

三角波以均匀的斜率振荡,直到它遇到最小或最大值,然后斜率反转。

两件事情制定出在这里:

  • 功能的起源将在波
  • 波振荡的中间开始从x-x

我们希望以0开始输出并且仅包括正值

function triangle(t, a) { 
    return Math.abs(((t + a/2) % a) - a/2); 
} 

让我们尝试一下

for (var i=0; i<20; i++) { 
    console.log(i, triangle(i, 10)); 
} 

输出

0 0 
1 1 
2 2 
3 3 
4 4 
5 5 
6 4 
7 3 
8 2 
9 1 
10 0 
11 1 
12 2 
13 3 
14 4 
15 5 
16 4 
17 3 
18 2 
19 1 

所以,当我们调用triangle(i, 10)10是 “月经”。这告诉我们在重复之前我们想要在我们的函数中有多少步骤。

6一个时期将会给我们6个值,0, 1, 2, 3, 2, 1

4一个时期将会给我们4个值,0, 1, 2, 1

如果你想从0-9去,你会需要一段20

+0

这是锯齿形的版本。可用于重置为0 'function sawtooth(t,a){Math.abs(((t + a)%a)); }' – veganista 2016-08-02 14:02:42

2

这里有一个:

(x&8)+(x&7)*((~x&8)/4-1) 

这将给你

0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1,0,1,... 

当然有实际上是有一个条件,只是被隐藏了的按位运算。

另一种可能性是三角波计数:

(x^((x&8)/-8))&7 

这确实

0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0,0,... 

再有一个隐藏条件是翻转位,当它中途得到。