我有两个问题,第一个是如何分别访问我的数组中的索引,因为我的[n] [0]的console.log会产生两个值 - x和y。其次,对于蝴蝶曲线https://en.wikipedia.org/wiki/Butterfly_curve_%28transcendental%29,我如何确定t的值?并通过一定的最小值和最大值重申。需要逻辑支持。
到目前为止,这是我的进展。
/*function drawButterFly(n){
c.beginPath();
console.log(n[2])
for (var i = 0; i < n.length; i++){
if (i === 0) {
c.moveTo();
} else {
c.lineTo();
}
c.stroke();
}
}*/
function butterFly() {
var r = 5;
var N = 3;
var value = [];
for (var a = 0.2; a < 2*Math.PI; a = a + 0.1){
value.push(a);
}
var t = value[Math.floor(Math.random()*value.length)];
var cos = r*Math.cos(t)*( (Math.exp(Math.cos(t))) - (2*Math.cos(4*t)) - (Math.sin(t/12)^5) );
var sin = r*Math.sin(t)*( (Math.exp(Math.cos(t))) - (2*Math.cos(4*t)) - (Math.sin(t/12)^5) );
var n = [];
for (var u = 0; u < N; u++){
var x = sin * -u;
var y = cos * -u;
n.push([x,y]);
}
drawButterFly(n);
}
答案 0 :(得分:2)
由于您在array
推送n.push([x,y])
,因此您可以使用n[0][0]
访问第一个元素的x组件,并使用{{1}访问同一元素的y组件}
示例:
n[0][1]
至于var n = [];
n.push( ["x", "y"] );
console.log( n[0][0] );
console.log( n[0][1] );
的有用值 - 在您显示的图像中,您会注意到相同的蝴蝶以不同的大小绘制了几次。要绘制完整的蝴蝶,您需要使用[0..2pi]的t范围。如果要绘制两只蝴蝶,则需要使用范围[0..4pi]。这就是圆圈在同一时期的循环。然而,与圆形不同,每个循环都不会覆盖前一个循环。
这是一个快速而令人讨厌的例子:
t
function byId(id) {
return document.getElementById(id);
}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt) {
butterFly();
}
function butterFly() {
var pointArray = [];
var stepSize = 0.05; // ~125 steps for every 360°
var upperLimit = 4 * Math.PI;
var scale = 20;
for (var t = 0.0; t < upperLimit; t += stepSize) {
var xVal = Math.sin(t) * ((Math.exp(Math.cos(t))) - (2 * Math.cos(4 * t)) - (Math.pow(Math.sin(t / 12), 5)));
var yVal = Math.cos(t) * ((Math.exp(Math.cos(t))) - (2 * Math.cos(4 * t)) - (Math.pow(Math.sin(t / 12), 5)));
pointArray.push([scale * xVal, -scale * yVal]); // -1 value since screen-y direction is opposite direction to cartesian coords y
}
drawButterFly(pointArray);
}
function drawButterFly(pointArray) {
var can = byId('myCan');
var ctx = can.getContext('2d');
var originX, originY;
originX = can.width / 2;
originY = can.height / 2;
ctx.beginPath();
for (var i = 0; i < pointArray.length; i++) {
if (i === 0) {
ctx.moveTo(originX + pointArray[i][0], originX + pointArray[i][1]);
} else {
ctx.lineTo(originX + pointArray[i][0], originY + pointArray[i][1]);
}
}
ctx.closePath();
ctx.stroke();
}
canvas {
border: solid 1px red;
}
答案 1 :(得分:2)
如果我没有弄错的话,蝴蝶曲线是作为一对参数方程给出的,这意味着你增加import pytest
exit_code = pytest.main("smoke_test_suite.py")
test_failures = bool(exit_code)
以获得曲线上的下一个t
点。换句话说,您的代码中(x, y)
应该代替t
使用u
,而t的值范围应为0 .. 24*pi
,因为sin(t / 12)
的范围是function getPoint(t, S, O) {
var cos_t = Math.cos(t);
var factor = Math.exp(cos_t) - 2 * Math.cos(4*t) - Math.pow(Math.sin(t/12), 5);
return {
x: S * Math.sin(t) * factor + O.x,
y: S * cos_t * factor + O.y
};
}
var canvas = document.getElementById("c");
canvas.width = 300;
canvas.height = 300;
var ctx = canvas.getContext("2d");
// First path
ctx.beginPath();
ctx.strokeStyle = 'blue';
var offset = {x:150, y:120};
var scale = 40;
var maxT = 24 * Math.PI;
var p = getPoint(0, scale, offset);
ctx.moveTo(p.x, canvas.height - p.y);
for (var t = 0.01; t <= maxT; t += 0.01) {
p = getPoint(t, scale, offset);
ctx.lineTo(p.x, canvas.height - p.y);
}
ctx.stroke();
1}}有其独特的价值观。)
这是一个演示将曲线绘制到画布的版本:
#c {
border: solid 1px black;
}
<canvas id="c"></canvas>
y = 0
有一点需要注意:画布的顶部是canvas.height - y
,因此您需要反转y(即function getPoint(t, S, O) {
var cos_t = Math.cos(t);
var factor = Math.exp(cos_t) - 2 * Math.cos(4*t) - Math.pow(Math.sin(t/12), 5);
return {
x: S * Math.sin(t) * factor + O.x,
y: S * cos_t * factor + O.y
};
}
var canvas = document.getElementById("c");
canvas.width = 300;
canvas.height = 300;
var ctx = canvas.getContext("2d");
var offset = {x:150, y:120};
var scale = 40;
var maxT = 24 * Math.PI;
var animationID;
var started = false;
var t = 0;
document.getElementById('start').addEventListener('click', function(e) {
e.preventDefault();
if (!started) {
animationID = requestAnimationFrame(animate);
started = true;
}
});
document.getElementById('pause').addEventListener('click', function(e) {
e.preventDefault();
if (started) {
cancelAnimationFrame(animationID);
started = false;
}
});
function animate() {
animationID = requestAnimationFrame(animate);
var p = getPoint(t, scale, offset);
if (t === 0) {
ctx.beginPath();
ctx.strokeStyle = 'blue';
ctx.moveTo(p.x, canvas.height - p.y);
t += 0.01;
} else if (t < maxT) {
ctx.lineTo(p.x, canvas.height - p.y);
ctx.stroke();
t += 0.01;
} else {
cancelAnimationFrame(animationID);
}
}
)以使曲线正确定位。
根据royhowie的要求,这是一个使用requestAnimationFrame
的动画版本:
#c {
border: solid 1px black;
}
<div>
<button id="start">Start</button>
<button id="pause">Pause</button>
</div>
<canvas id="c"></canvas>
public class Draw extends JPanel {
private static final long serialVersionUID = 1L;
public Draw(int rx, int ry)
{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
this.setBackground(Color.WHITE);
g.setColor(Color.BLUE);
try{
g.fillRect(rx, ry, 5, 5);
Thread.sleep(1000);
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
}
}
public static void main(String[] args) {
JFrame f = new JFrame("Title");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
for (int i = 1; i < 40; i++) {
Random r = new Random();
int rx = r.nextInt(40);
int ry = r.nextInt(40);
Draw d = new Draw(rx, ry);
f.add(d);
f.setSize(400, 400);
f.setVisible(true);
}
}
}
答案 2 :(得分:1)
问题1
对于任意整数i
,请n[i] = [xi, yi]
。然后可以通过xi
和n[i][0]
通过yi
n[i][1]
问题2
对于t
的值,我确定您要使用子整数值,因此我建议使用代表图表“分辨率”的常量增量值。
我们称之为dt
。另外,我建议您将变量名称从单个字母更改为更具描述性的内容,例如min_t
和max_t
,而不是n
我将调用您的数组{{1 }}
points.
我不确定该函数内部的其他循环是什么,但是如果你需要它,你可以适应上面的模式。
用法示例:function drawButterFly(points){
for (var i = 0, n = points.count; i < n; ++i) {
var x = points[i][0];
var y = points[i][1];
...
}
}
function butterFly(min_t, max_t, dt, r) {
var points = [];
for (var t = min_t; t < max_t; t+=dt){
var x = r*Math.sin(t)*...
var y = r*Math.cos(t)*...
points.push([x,y]);
}
drawButterFly(points, dt);
}
- &gt; butterFly(0, 10, 0.01, 3)
从t
升级到0
,增量为{{1}},10
答案 3 :(得分:0)
关于你的第一个问题,用一个对象替换包含x
和y
坐标的多维数组是一个更好的选择。然后,当迭代数组时,您可以检查对象值。
所以而不是:
n.push([x,y]);
你应该这样做:
m.push({
'xPos' : x,
'yPos' : y
})
稍后您可以m.xPos
或m.yPos
访问此内容
然后,您可以按对象文字名称访问x和y值。
关于第二个问题:对于蝴蝶曲线的良好伪代码实现,您可以查看Paul Burke网站:http://paulbourke.net/geometry/butterfly/。因此,t
就是:
t = i * 24.0 * PI / N;
如您所见t
是一个参数值,当迭代数组时,每个步骤都会递增。