I've managed to get a function working which will calculate and return the angle between one point and another. I've called it the lookAt function, because it's basically causing one transform to look at another one. Here it is:
this.lookAt = function(target) {
var d = target.subtract(this.position)
this.rotation = Math.atan2(d.y, d.x) + Math.PI/2;
return this.rotation;
}
In this function's context, this refers to a surrounding object which has the variables rotation (a rotation in radians) and position, a Vector2 class which has a few basic math functions and stores x and y values. d is a Vector2 created by calling a helper function on the variable target, which subtracts one Vector2 from another.
This works as expected--if I call this function on an object, the rotation correctly "looks at" the target. However, I'd like to know why I had to add π / 2 (which is 1 radian, correct?). I got the original equation from this question, but the answer did not add π / 2 to the equation, whereas I have to.
Could somebody explain the math behind this? Also, I haven't gotten to that much trigonometry yet (besides what my Algebra course introduced me to), so please explain this as if you were talking to a very small child. :-)
Related
I'm looking to have an algorithm that can randomly draw a "squiggly wiggly" pattern as per the picture.
It would be nice if it were progressively drawn as you would draw it with a pen and if it were based on speed, acceleration and forces like a double pendulum animation might be.
This would be for javascript in the p5 library.
Is there some way of producing this that a) looks hand drawn and b) fills a page, somewhat like a Hilbert curve?
Very interested to hear ideas of how this could be produced, regardless of whether there is some kind of formal algorithm, although a formal algorithm would be best.
Cheers
I can think of two solutions, but there could be more as I'm not very good at coding in general yet.
First of all, you can use perlin noise. With the code
var noiseSeeds = [];
//This changes the noise value over time
var noiseTime = 0;
var x = 0;
var y = 0;
function setup() {
createCanvas(400, 400);
//This will help for making two separate noise values later
noiseSeeds = [random(100), random(100)];
}
function draw() {
//Finding the x value
noiseSeed(noiseSeeds[0]);
x = noise(noiseTime)*400;
//Finding the y value
noiseSeed(noiseSeeds[1]);
y = noise(noiseTime)*400;
//Increasing the noise Time so the next value is slightly different
noiseTime += 0.01;
//Draw the point
stroke(0);
strokeWeight(10);
point(x, y);
}
You can create a scribble on screen. You would have to use createGraphics()in some way to make this more efficient. This method isn't the best because the values are generally closer to the center.
The second solution is to make a point that has two states - far away from an edge and close to an edge. While it is far away, the point would keep going in relatively the same direction with small velocity changes. However, the closer the point gets to the edges, the (exponentially) bigger the velocity changes so that the point curves away from the edge. I don't know exactly how you could implement this, but it could work.
I'm creating an app where a person (right now I'm using a cone-shape) is standing on some surface (right now I'm using a cylinder laid lengthwise) and I'd like their feet to orient toward some point (right now it's the center of the cylinder).
(edit: I just realized that my Z axis in this photo is pointing in the wrong direction; it should be pointing towards the camera, but the question remains unchanged.)
Here is a version of the code similar to what I'm trying to accomplish. https://codepen.io/liamcorbett/pen/YMWayJ (Use arrow keys to move the cone)
//...
person = CreatePerson();
person.mesh.up = new THREE.Vector3(0, 0, 1);
//
// ...
//
function updateObj(obj, aboutObj=false){
let mesh = obj.mesh;
if (aboutObj) {
mesh.lookAt(
aboutObj.mesh.position.x,
aboutObj.mesh.position.y,
mesh.position.z)
};
}
//
// ...
//
function animate() {
// ...
updateObj(person);
// ...
}
The code above gives me something similar to what I'm looking for, but the issue is that lookAt() seems to always point the local Positive Z-axis in some direction, and I'd much prefer that it point the local Negative Y-axis instead.
I'd prefer to not change the x,y,z axes of the model itself, as I feel that's going to be a pain to deal with when I'm applying other logic to the person object.
Is there a way to change which axis lookAt() uses? Or am I going to have to roll my own lookAt() function? Thanks ~
Is there a way to change which axis lookAt() uses?
No, the default local forward vector for 3D objects (excluding cameras) is (0, 0, 1). Unlike other engines, three.js does not allow to configure the forward vector, only the up vector. But this is not really helpful in your case.
You can try to transform the geometry in order to achieve a similar effect.
If you don't want to do this for some reasons and you still want to use Object3D.lookAt(), you have to compute a different target vector (so not the cylinder's center).
Even if the forward vector of the lookAt method can't be changed (as #Mugen87 said), you can still adjust the local rotation afterwards by knowing in advance the difference between the forward Z axis used, and the axis you consider your mesh to be "upward" (ex: a person standing up on the Y axis).
Basically, in your case, just add this line after the lookAt method :
mesh.rotateOnAxis( new THREE.Vector3(1,0,0), Math.PI * -0.5 );
And the cone will look up :)
I am currently working moving different cars around a race track. I am using the formula listed in
Canvas move object in circle
arccos (1- ( d ⁄ r ) 2 ⁄ 2 )
to vary the speed of the cars around the ends of the track and it works very well. What I don't understand is how the formula is derived. I have been working on trying to derive it from the second derivative of the arcsin or arccos but I can't get out the formula (so am guessing I'm walking the wrong path). Anyways, I am never comfortable using code I don't understand, so I would appreciate it if someone could shed some light on it for me.
As detailed in the linked question, the movement of an object along a circle can be parametrized with a single angle theta which in loose terms describes how many "revolutions" the object has already made. Now, the question is for which angle theta the object is at Euclidean distance d from the initial (current) position A:
In other words, if you fix the time step delta of your simulation, the problem can be restated as to how one should adjust (increment) the angle so that the object displaces within the time interval delta to distance d.
From the law of cosines, one gets:
d^2 = r^2 + r^2 - 2*r*r*cos(theta) = 2*r^2*(1 - cos(theta))
Thus:
cos(theta) = 1 - 1/2*(d/r)^2
theta = arccos(1 - 1/2*(d/r)^2)
As you can see in the picture, I have a line and two points(p1 and p4). what I need to do is to get snapped point of p1/p4 on the line and then use atan2 to calculate the angle between (p1 and p2) and (p3 and p4). Now, I have two formulas:
var anglep1p2 = Math.atan2(p2[1] - p1[1], p2[0] - p1[0]) * 180 / Math.PI;
var anglep4p3 = Math.atan2(p4[1] - p3[1], p4[0] - p3[0]) * 180 / Math.PI;
anglep1p2 is calculated 103.66797855556482
anglep4p3 is calculated -76.74971541138642
I wonder how does atan2 calculate those values?
thanks for any help
These answers do make sense. You are sort of calculating a the angle of a single line, starting from the positive x-axis. The way you calculate anglep1p2, it corresponds to the line drawn from p1 to p2.
If you plunk the origin of a coordinate system at the starting point p1 (you put it at p2 in your diagram), then the number you get should be the rotation from the positive x-axis to the line you drew - a bit over 90 degrees makes intuitive sense.
Your second result is flipped from your first (notice you used p4/p3 in the same order as your variable name, whereas you reversed this order in the p1/p2 case). To avoid confusion, I'd use the p1/p2 case to gain understanding, then apply it the same way to the other case once you know what you want.
If you have a specific geometry/relationship problem you need to figure out, you can provide the details and I might be able to help more specifically.
I wanted to make a reflection algorithm that avoided the sqrt function, and this is what I came up with:
Vector3D.prototype.reflectOver = function(vectorToReflectOver){ //return a reflected vector
var t = (vectorToReflectOver.dot(vectorToReflectOver))/(this.dot(vectorToReflectOver));
var reflectedVector = vectorToReflectOver.multiply(2).subtract(this.multiply(t));
return reflectedVector;
}
The reasoning behind it is that if we want to reflect a vector V_1 over another vector V_2, we want to find a vector V_3 such that V_2 + V_3 is the reflection vector. First we must find the vector t*V_1 such that t*V_1 - V_2 = V_3. This is what t is in the function. Any ideas?
Just to be clear, the dot function refers to a dot product, multiply multiplies a scalar to a vector, subtract subtracts two vectors. The function is called like so, v.reflectOver(n), where v and n are two vectors. Furthermore, this doesn't throw an error. This is a performance error, not a compiler or runtime error.
It's a little hard to say where you went wrong, but if you draw it out on paper, you should get something like this:
this.project_onto(other.as_unit_vector()).multiply(2).subtract(this)