var canvas = document.createElement("canvas");
canvas.width = innerWidth - 40;
canvas.height = innerHeight - 40;
canvas.style.border = "1px solid black";
var ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
var sliderChanged = true;
function createSlider(name,val,min,max){
var div = document.createElement("div");
div.textContent = name;
var slider = document.createElement("input");
var valSpan = document.createElement("span");
slider.type = "range";
slider.min = min;
slider.max = max;
slider.step = (max-min)/Math.floor(canvas.width * 0.7);
slider.value = val;
valSpan.textContent = val;
slider.addEventListener("mousemove",function(){
if(slider.value !== slider.lastValue){
slider.lastValue = slider.value;
valSpan.textContent = Number(slider.value).toFixed(3);
sliderChanged = true;
}
});
div.appendChild(slider);
div.appendChild(valSpan);
document.body.appendChild(div);
return slider;
}
var springTension = createSlider("Spring tension :",0.5,0,1);
var springStrength = createSlider("Spring strength :",5,0.1,20);
var damping = createSlider("Damping :",0.1,0.01,1.0);
var armMass = createSlider("Swing arm mass:",200,1,1000);
var armHeight = createSlider("Swing arm height:",Math.floor(canvas.height * 0.6),Math.floor(canvas.height * 0.1),Math.floor(canvas.height * 0.8));
var mouse = (function () {
function preventDefault(e) {
e.preventDefault();
}
var mouse = {
x : 0,
y : 0,
bounds : null,
mouseEvents : "mousemove".split(",")
};
var m = mouse;
function mouseMove(e) {
var t = e.type;
m.bounds = m.element.getBoundingClientRect();
m.x = e.pageX - m.bounds.left;
m.y = e.pageY - m.bounds.top;
}
m.updateBounds = function () {
}
m.start = function (element) {
m.element = element === undefined ? document : element;
m.mouseEvents.forEach(n => {
m.element.addEventListener(n, mouseMove);
});
m.updateBounds();
}
return mouse;
})();
mouse.start(canvas);
//=====================================================================================================================
// Answer start here
const springCof = 0.3; // characteristic of the spring see Hooks law
const dampingC = 0.05; // amount of damping as a factor of rotational speed.
const springTensionC = 0.5; // min tension on the spring ( 1 subtract the amount the spring is stretched from relaxed length)
// details of the swing arm
var pole = {};
pole.mass = 200;
pole.dr = 0;
pole.rot = 0;
pole.piviotRadius = canvas.height * 0.01;
pole.topWidth = canvas.height * 0.02
pole.centerWidth = canvas.height * 0.04
pole.baseWidth = canvas.height * 0.02
pole.x = canvas.width / 2;
pole.y = canvas.height * 0.7;
pole.height = canvas.height * 0.6; // from rotation point to top
pole.baseHeight = canvas.height * 0.1;
pole.spring = {};
pole.spring.y = canvas.height * 0.1;
pole.spring.x = 0;
pole.spring.baseY = canvas.height * 0.2;
pole.spring.baseX = 0;
pole.spring.relaxLength = Math.hypot(pole.spring.x -pole.spring.baseX, pole.spring.y - pole.spring.baseY);
pole.spring.relaxLength *= springTensionC;
pole.spring.cof = springCof; // characteristic of the spring see Hooks law
pole.spring.damp = dampingC; // amount of damping as a factor of rotational speed.
// Basicly the pivot is rusty and provides the damping.
function setPoleValues(pole){
pole.height = Number(armHeight.value);
pole.mass = Number(armMass.value);
var lookRight = Math.pow(pole.mass,1/3)/Math.pow(1000,1/3);
pole.topWidth = canvas.height * (0.001 + 0.02 * lookRight);
pole.centerWidth = canvas.height * (0.004 + 0.04 * lookRight)
pole.baseWidth = canvas.height * (0.004 + 0.02 * lookRight)
pole.spring.relaxLength = Math.hypot(pole.spring.x -pole.spring.baseX, pole.spring.y - pole.spring.baseY);
pole.spring.relaxLength *= 1-Number(springTension.value);
pole.spring.cof = Number(springStrength.value);
pole.spring.damp = Number(damping.value);
}
// draws a spring
function drawSpring(x1,y1,x2,y2,width){
var x = x2 - x1;
var y = y2 - y1;
var dist = Math.sqrt(x * x + y * y);
var nx = x / dist;
var ny = y / dist;
ctx.beginPath();
ctx.lineWidth = 1;
ctx.moveTo(x1,y1);
var step = 0.1;
for(var i = step; i < 1-step; i += step){
for(var j = 0; j < 1; j += 0.1){
var xx = x1 + x * (i + j * step);
var yy = y1 + y * (i + j * step);
xx -= Math.sin(j * Math.PI * 2) * ny * width;
yy += Math.sin(j * Math.PI * 2) * nx * width;
ctx.lineTo(xx,yy);
}
}
ctx.lineTo(x2,y2);
ctx.stroke();
return dist;
}
// draws the pole and also calculates the position of the pole top
// and details about the spring
function drawPole(pole){
ctx.fillStyle = "red";
ctx.strokeStyle = "black";
ctx.lineWidth = 4;
ctx.lineJoin = "round";
ctx.setTransform(1,0,0,1,pole.x,pole.y)
ctx.rotate(pole.rot)
ctx.beginPath();
ctx.moveTo( - pole.topWidth,- pole.height);
ctx.lineTo(pole.topWidth,- pole.height);
ctx.lineTo(pole.centerWidth,0);
ctx.lineTo(pole.baseWidth, pole.baseHeight);
ctx.lineTo( - pole.baseWidth, pole.baseHeight);
ctx.lineTo( - pole.centerWidth,0);
ctx.closePath();
ctx.stroke();
ctx.fill();
ctx.fillStyle = "yellow";
ctx.beginPath();
ctx.arc( pole.spring.x,pole.spring.y,pole.piviotRadius * 0.5,0,Math.PI*2);
ctx.stroke();
ctx.fill();
ctx.setTransform(1,0,0,1,0,0)
ctx.fillStyle = "blue";
ctx.beginPath();
ctx.arc(pole.x,pole.y,pole.piviotRadius,0,Math.PI*2);
ctx.stroke();
ctx.fill();
ctx.fillStyle = "yellow";
ctx.beginPath();
ctx.arc(pole.x + pole.spring.baseX,pole.y + pole.spring.baseY,pole.piviotRadius * 0.5,0,Math.PI*2);
ctx.stroke();
ctx.fill();
var xdx = Math.cos(pole.rot);
var xdy = Math.sin(pole.rot);
var xx = pole.spring.realX = xdx * pole.spring.x - xdy * pole.spring.y;
var yy = pole.spring.realY = xdy * pole.spring.x + xdx * pole.spring.y;
pole.spring.length = Math.hypot(pole.x + xx -(pole.x + pole.spring.baseX), pole.y + yy- (pole.y + pole.spring.baseY));
pole.spring.direction = Math.atan2(pole.y + pole.spring.baseY - (pole.y + yy),pole.x + pole.spring.baseX-(pole.x + xx ))
pole.topX = pole.x + xdy * pole.height; // at 90 deg
pole.topY = pole.y - xdx * pole.height;
drawSpring(pole.x + xx,pole.y + yy,pole.x + pole.spring.baseX,pole.y + pole.spring.baseY,3);
}
// applies a force.
// As the the swing arm rotation point is fixed this only extracts the
// angular acceleration from the force
function applyAccel(pole,x,y,ax, ay){ // x,y where the force is applied,
// ax,ay the acceleration of the force
var direction = Math.atan2(ay,ax);
var toCenter = Math.atan2(pole.y - y, pole.x - x);
var pheta = toCenter - direction;
var dist = Math.hypot(x-pole.x,y-pole.y);
var force = Math.hypot(ax,ay) * pole.mass;
var Fa = Math.sin(pheta) * force;
Fa = Fa / (pole.mass * dist);
pole.dr += Fa;// now add that to the box delta r
}
function applyForce(pole, x, y, fx, fy){ // x,y where the force is applied,
// fx,fy the force
var direction = Math.atan2(fy,fx);
var toCenter = Math.atan2(pole.y - y, pole.x - x);
var pheta = toCenter - direction;
var dist = Math.hypot(x-pole.x,y-pole.y);
var force = Math.hypot(fx,fy) ;
var Fa = Math.sin(pheta) * force;
Fa = Fa / (pole.mass * dist);
pole.dr += Fa;// now add that to the box delta r
}
// for calculating the acceleration of the mouse
var lastX = 0;
var speed = {};
speed.x = 0;
speed.y = 0;
speed.lx = 0;
speed.ly = 0;
function update2(timer){
globalTime = timer;
ctx.setTransform(1,0,0,1,0,0); // reset transform
ctx.globalAlpha = 1; // reset alpha
ctx.clearRect(0,0,canvas.width,canvas.height);
if(sliderChanged){
setPoleValues(pole);
sliderChanged;
}
if(lastX == undefined){
lastX = mouse.x;
getPoleDetails(pole);
}
drawPole(pole);
// move the pole
pole.x = mouse.x;
// get the acceleration of the mouse movement
speed.x = (lastX - mouse.x);
speed.y = 0;
// apply the mouse movement acceleration to the top of the pole
// Accel is the change in mouse speed
applyAccel(pole,pole.topX,pole.topY,speed.x - speed.lx, speed.y - speed.ly);
// apply the springs force (note the spring is never compressed)
applyForce(
pole,
pole.x + pole.spring.realX,
pole.y + pole.spring.realY,
Math.cos(pole.spring.direction) * (pole.spring.length - pole.spring.relaxLength) * pole.spring.cof,
Math.sin(pole.spring.direction) * (pole.spring.length - pole.spring.relaxLength) * pole.spring.cof
)
// add the change in rotation
pole.rot += pole.dr;
// dampen the rotation
pole.dr *= 1-pole.spring.damp;
lastX = mouse.x
speed.lx = speed.x;
speed.ly = speed.y
if((mouse.buttonRaw & 4)!== 4){
requestAnimationFrame(update2);
}else{
log("done");
}
}
requestAnimationFrame(update2);
touchesMoved()
mengembalikan gerakan yang sangat kecil setiap pembaruan, yang membuat perilaku objek saya menjadi sangat aneh. Dan mungkin berguna untuk menggunakan SceneKit, tetapi sebenarnya saya baru mengenal SpriteKit, dan hampir tidak memiliki pengalaman dalam SceneKit, jadi saya mungkin tidak dapat menerapkan efek ini pada akhirnya. Bagaimanapun, terima kasih atas bantuan dan kesabaran Anda. - person Source   schedule 13.11.2016