好问题!我喜欢Tom10的答案(在标记上是+1),但不知道它是否可以在不使用太多三角法的情况下完成。下面是一个简单的解决方案,然后是一个解释。
//slope is a constant,0.414…;calculate it just one
var slope=math.tan(math.pi/8);
//对每个x,y点执行此操作
变量s1=x*斜率+y>0?0:1;
变量s2=y*坡度+x>0?0:1;
变量s3=y*斜率-x<0?0:1;
变量s4=x*斜率-y>0?0:1;
var段=4*s4+2*(s2^s4)+(s1^s2^s3^s4);
< /代码>
这将在0和7之间设置segment下面是一个有2000个随机点的例子(答案末尾是完整的源代码)。使用sprite速度的x,y值,您可以使用分段值来选取适当的sprite图像。
< TADAA!
那么这是如何工作的?oursegmentexpression does look a bit cryptic.
观察一:我们要将围绕该点的圆分割成8段等角尺寸。360/8=每段45度。8个分段中的4个位于X和Y轴两侧的其中一个的中心,每个分段以45/2=22.5度的角度进行切割。
观察二:平面上直线的方程,a*x+b*y+c=0,当变成不等式时,a*x+b*y+c>0可用于测试A点位于哪一侧。我们的四条线都穿过原点(x=0,y=0),因此力c=0。此外,它们都与x或y轴成22.5度角。这就得到了四行方程:
y=x*tan(22.5);y=-x*tan(22.5);
x=y*tan(22.5);x=-y*tan(22.5)
变成了不平等:
X*棕褐色(22.5)-Y>0;
x*tan(22.5)+y>0;
Y*棕褐色(22.5)-X>0;
Y*棕褐色(22.5)+X>0
测试一个给定点的不等式可以让我们知道它所在的每一行的每一面:
观察三:我们可以组合测试结果以获得我们想要的段号模式。这是一个视觉分解:
按顺序:4*s4,2*(s2^s4)and the sum4*s4+2*(s2^s4)
(符号^是javascript xor运算符。)
这里是s1^s2^s3^s4,首先自己添加,然后添加到4*s4+2*(s2^s4)
额外学分:Can we tweak the calculation to use only integer algorithm?是--如果已知x和y是整数,我们可以将不等式的两边乘以某个常数(和舍入),从而得到完全整数的数学。(然而,在数字总是双精度浮点的javascript上,这将丢失。):
var s1=x*414+y*1000>0?0:1;
变量s2=y*414+x*1000>0?0:1;
变量s3=y*414-x*1000<0?0:1;
变量s4=x*414-y*1000>0?0:1;
< /代码>
以上示例的完整源代码:(只需将其放入新的HTML文件中,然后在任何浏览器中打开)
(请参阅jsbin上的实时演示)
<html>
&头;
<style type=“text/css”>
.dot位置:绝对;字体:10px Arial
.d0颜色:ff0000;
.d1颜色:ffbf00;
.d2颜色:7fcc00;
.d3颜色:00ff7f;
.d4颜色:00ffff;
.d5颜色:5555ff;
.d6颜色:af00ff;
.d7颜色:ff00bf;
&风格/风格;
<script type=“text/javascript”src=“http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js”></script>
<script type=“text/javascript”>
$(函数){
var$canvas=美元(“canvas”);
var canvassize=300;
VaR计数=2000;
var slope=math.tan(math.pi/8);
$canvas.css(宽度:拉票,高度:拉票);
对于(var i=0;i<count;++i){
//生成随机点
var x=math.random()-0.5;
变量y=math.random()-0.5;
//画出我们的点
var$point=$(“<DIV class='dot'></DIV>”)
CSS({)
左:数学楼层((X+0.5)*拉票)-3,
顶部:数学楼层((Y+0.5)*拉票)-6)
.appendto($canvas);
//找出我们的观点所在的部分
变量s1=x*斜率+y>0?0:1;
变量s2=y*坡度+x>0?0:1;
变量s3=y*斜率-x<0?0:1;
变量s4=x*斜率-y>0?0:1;
var段=4*s4+2*(s2^s4)+(s1^s2^s3^s4);
//修改点的HTML内容和颜色
//(通过其CSS类)来指示其段
美元点
文本(段)
.addclass(“d”+段);
}
(});
& /脚本& GT;
和/头& GT;
和身体;
<div id=“canvas”style=“position:absolute;border:1px solid blue”>
&L/DIV & GT;
和/身体;
& lt//html & gt;
< /代码>
但不知道是否可以不用太多的三角学来完成。下面是一个简单的解决方案,然后是一个解释。
// slope is a constant, 0.414...; calculate it just once
var slope = Math.tan(Math.PI/8);
// do this for each x,y point
var s1 = x * slope + y > 0 ? 0 : 1;
var s2 = y * slope + x > 0 ? 0 : 1;
var s3 = y * slope - x < 0 ? 0 : 1;
var s4 = x * slope - y > 0 ? 0 : 1;
var segment = 4 * s4 + 2 * (s2 ^ s4) + (s1 ^ s2 ^ s3 ^ s4);
这将设置segment
介于0和7之间。下面是一个有2000个随机点的例子(答案末尾是完整的源代码)。使用sprite速度的x,y值,可以使用分段值来选取合适的sprite图像。
塔达亚!
那么这是如何工作的呢?我们的段表达式看起来有点神秘。
观察一:我们要将围绕点的圆分割成8段等角尺寸。360/8=每段45度。8个分段中的4个位于X轴和Y轴的其中一侧的中心,每个分段的切割角度为45/2=22.5度。
观察二平面上直线的方程,a*x + b*y + c = 0
当变成不平等时,a*x + b*y + c > 0
可用于测试点位于直线的哪一侧。我们的四条线都穿过原点(x=0,y=0),因此力c=0。此外,它们都与x或y轴成22.5度角。这就得到了四条直线方程:
y=x*tan(22.5);y=-x*tan(22.5);
x=y*tan(22.5);x=-y*tan(22.5)
变成不平等,我们得到:
X*棕褐色(22.5)-Y>0;
x*tan(22.5)+y>0;
Y*棕褐色(22.5)-X>0;
Y*棕褐色(22.5)+X>0
测试一个给定点的不等式可以让我们知道它所在的每一行的每一面:
观察三:我们可以结合测试结果来获得所需的段号模式。这是一个视觉分解:
顺序:4 * s4
,2 * (s2 ^ s4)
和和4 * s4 + 2 * (s2 ^ s4)
(符号^是javascript xor运算符。)
这里是s1 ^ s2 ^ s3 ^ s4
,首先单独添加,然后添加到4*s4+2*(s2^s4)
额外贷款:我们能把计算调整为只使用整数算术吗?是的--如果X和Y已知为整数,我们可以将不等式的两边乘以某个常数(并取整),得到完全整数的数学表达式。(然而,在数字总是双精度浮点的javascript上,这将丢失。)
var s1 = x * 414 + y * 1000 > 0 ? 0 : 1;
var s2 = y * 414 + x * 1000 > 0 ? 0 : 1;
var s3 = y * 414 - x * 1000 < 0 ? 0 : 1;
var s4 = x * 414 - y * 1000 > 0 ? 0 : 1;
以上示例的完整源代码:(只需将其放到新的HTML文件中,然后在任何浏览器中打开即可)
(see as a live demo on jsbin)
<html>
<head>
<style type="text/css">
.dot { position: absolute; font: 10px Arial }
.d0 { color: #FF0000; }
.d1 { color: #FFBF00; }
.d2 { color: #7fcc00; }
.d3 { color: #00FF7F; }
.d4 { color: #00FFFF; }
.d5 { color: #5555FF; }
.d6 { color: #aF00FF; }
.d7 { color: #FF00BF; }
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
var $canvas = $("#canvas");
var canvasSize = 300;
var count = 2000;
var slope = Math.tan(Math.PI/8);
$canvas.css({ width: canvasSize, height: canvasSize });
for (var i = 0; i < count; ++i) {
// generate a random point
var x = Math.random() - 0.5;
var y = Math.random() - 0.5;
// draw our point
var $point = $("<div class='dot'></div>")
.css({
left: Math.floor((x + 0.5) * canvasSize) - 3,
top: Math.floor((y + 0.5) * canvasSize) - 6 })
.appendTo($canvas);
// figure out in what segment our point lies
var s1 = x * slope + y > 0 ? 0 : 1;
var s2 = y * slope + x > 0 ? 0 : 1;
var s3 = y * slope - x < 0 ? 0 : 1;
var s4 = x * slope - y > 0 ? 0 : 1;
var segment = 4 * s4 + 2 * (s2 ^ s4) + (s1 ^ s2 ^ s3 ^ s4);
// modify the point's html content and color
// (via its CSS class) to indicate its segment
$point
.text(segment)
.addClass("d" + segment);
}
});
</script>
</head>
<body>
<div id="canvas" style="position: absolute; border: 1px solid blue">
</div>
</body>
</html>