apply rotation on dist function p5js. Rotation causes dist to malfunction - rotation

I am trying to visualize some data and I require interactivity. I represent the entities that I want to visualize as balls that move like a solar system. in order to gain this I used rotation and translation. However, when I use the distance function to show the name of the entity, it malfunctions and shows the name elsewhere, and the interaction needs to be made somewhere else too unlike what I have in mind. Here is a very simplified version of my code with comments.
//the angle (t) and theta factor as tt
var t=0;
var tt=0.01;
function setup()
{
//creating canvas to darw
createCanvas(600,600);
}
function draw()
{
background(255);
//translating the 0,0 point to the center of the canvas
translate(width/2,height/2);
//applying rotation on the matrix
rotate(1);
//gaining circular movement through sine and cosine oscillation
x=sin(t)*100;
y=cos(t)*50;
//drawing the ball
ellipse(x,y,10,10);
//when the mouse is inside the ball, a text is supposed to appear with the ball that says "on it"
if(dist(mouseX,mouseY,width/2+x,height/2+y)<5)
{
text("on it",x,y);
}
//incrementing the angle
t+=tt;
}

Nothing is malfunctioning. Your problem is caused by the fact that mouseX and mouseY are always in screen space, where your coordinates are in model space after you do the translation and rotate.
You're going to have to project the mouse coordinates into model space. Unfortunately P5.js doesn't have the modelX() and modelY() functions that Processing has, so you're going to have to do this yourself. See George's answer to this question for an excellent guide on exactly how to do that.
The other option I can think of is to do all of your drawing to a P5.Renderer without the rotate or translate, so render space and model space will be the same. Then rotate the whole thing before you draw it. Not sure if that'll work exactly how you want it to, but it's worth investigating. More info can be found in the reference.

Related

How to prevent culling or simply redraw on iTowns globe rotation outside of mouse, touch or key events?

I'm attempting to rotate the "globe" in iTowns in real time by adding a frame requester (in three.js this would be the requestAnimationFrame loop).
I am attempting to use iTowns to provide a real time 3D earth map simulation. As part of this I have an interval firing every second and playhead controls to manipulate time. I'm trying to rotate an earth representation along the z-axis because in iTowns that is the polar axis. I need to check the time every frame because I can calculate the earth rotation in radians/sec quite easily and as I manipulate the playhead to speed up time I can get a fluidly rotating earth. Also I'm utilizing the default Ortho layer provided in iTowns to add a geographic layer on top of the blue marble default.
// this.view is an iTowns/src/Core/Prefab/GlobeView
const globeLayer = this.view.getLayerById("globe");
const globe = globeLayer.object3d;
this.view.addFrameRequester(MAIN_LOOP_EVENTS.UPDATE_START, () => {
globe.rotation.z = ConversionUtils.toRadians(this.globals.getSceneRotation());
});
The globe rotates, however I believe iTowns is performing some sort of culling of the map tiles/globe. What happens is at some point as the earth rotation is taking place a portion of the globe no longer renders. If this was related to the Ortho layer I believe the blue marble would still show. We have another version of the application without any iTowns and we can rotate a Three.js SphereGeometry without any culling using the same mechanics; so I am 99% sure it is not an issue with Three.js unless iTowns is doing something I don't see.
How do I prevent the culling, which I see is documented as an optimization? Better yet, how can I tell it to redraw properly?
I've tried the following but to no apparent effect:
this.view.notifyChange(globeLayer, true);
this.view.notifyChange(undefined, true);
this.view.notifyChange(this.view.controls.camera, true);
globe.updateMatrixWorld(true);
There is "culling" logic in:
- iTowns/src/Core/Prefab/GlobeLayer.js
- iTowns/src/Layer/TiledGeometryLayer.js
This is invoked from iTowns/src/Core/MainLoop.js. Bubbling up to the method scheduleViewUpdate which is invoked on iTowns/src/Core/View.js notifyChange.
Further digging leads me to believe iTowns/src/Controls/GlobeControls.js, specifically the cameraTarget attribute that I can't manipulate, is either the answer or is related.
I am hoping I am missing something and there is a way to code this up. Alternatively, I realize the suggestion may be fork or PR iTowns.
It is worth noting I do not want to change the camera position, just rotate the globe because there are other objects also moving in the scene i.e. satellites in orbit.

P5.JS: Collisions?

I have an idea of getting a circle grow in size if anywhere in the circle's area there is this object called "food". Though I have no idea how to implement it on my code. I have tried but of course the whole concept of my idea was off in trying to pull this off.
this.touch = function(){
if (x > this.x && y > this.y){
this.radius += 0.5;
}
}
This is one of my functions in a constructor, the variable x and y is referencing the "food"'s position. The this.(variables) are referring to the object reacting to the food.
The code snippet on top does not work simply for the fact that I am asking the object to increase in size based on x and y positions, and that just doesn't work for my concept.
Can anyone give me some tips or send a link to something which could help.
Thanks in advance!
I'd start by googling something like collision detection for a ton of results.
You can also narrow your search by adding the type of shapes you're talking about. For example, if your food is shown as a point, you might google (point circle collision detection". If your food is shown as a circle, you might google "circle circle collision detection".
If you're dealing with circles, you basically want to check the distance from the center of the circle. If that distance is less than the radius of the circle, then you have a collision. The dist() function will come in handy here.
Shameless self-promotion: here is a tutorial on collision detection. It's written for Processing, but all of the concepts apply to P5.js as well.

How do I place an element in front of the camera, facing it regardless of where it is?

I have this simple scene with a "tooltip" entity composed of some data, I'd like to know how to position it in front of the camera. The tooltip will have to face certain points a few meters away so the user can see it. It must obey camera direction (it can be gathered by calculating it from previousPoint to nextPoint where the camera will move), but only y axis (can't be tilted or anything like that).I tried digging through math but couldn't understand good enough to employ a solution for this little project; I appreciate all the help!
setTimeout(function(){
var camera = document.getElementById("cameraS");
var tt = document.getElementById("ttS");
var cameraPos = camera.getAttribute('position');
var ttPos = tt.getAttribute('position');
tt.setAttribute('position', cameraPos);
tt.setAttribute('rotation', {'y': -90});
}, 5000);
JSFiddle
EDIT
I made an image showing what I'm after: http://imgur.com/a/eDhqE
I have point A and point B; the camera will play an animation moving from previous point to the next, and upon reaching there the tooltip will be displayed a few meters away from the point (box) so we can see it. It must take camera orientation into consideration but it must be perpendicular to the ground (can't be tilted).
There is a command THREE.Object.lookAt(THREE.Vector3); that will rotate an object (assuming (0.0,1.0,0.0) is up) to face a vector. You can use this to have it face your camera.
If you only want Y rotation, you can copy the current rotation, then do look at, then copy the rotation.x and rotation.z from the previous frame rotation copy - so that way it'll only correct the y with .lookAt because you reset x and z.

How to find nearest object with three.js

I have a bunch of data and I know their lat/lon position (circles on the image). Now I have a camera in three.js and I know it's position, rotation and which way is north from it's perspective.
I want to go on top of these circles on mouse click but I'd like that the program would choose the closest one to the player and it should also be in the current field of view.
I've tried finding the angle between camera look direction and circle's position but it still moves quite randomly.
Any ideas where to start with this?
I'm not totally sure what you're asking regarding the "going on top of the circles and mouse click" part but here's a utility function for getting the distance between a camera and a point you know the x, y, z coordinates for.
var getCameraDistanceFrom = function(camera,x,y,z) {
var cameraDistance = new THREE.Vector3();
var target = new THREE.Vector3(x,y,z);
cameraDistance.subVectors(camera.position, target);
return cameraDistance.length();
};
This answer seems to have a good way to check if an object is in the camera's field of view: Determine if a mesh is visible on the viewport according to current camera

What object rotate(theta) rotates in this example?

In this example I am confused about the use of rotate and translate, more specifically,
// The earth rotates around the sun
pushMatrix();
rotate(theta);
translate(50,0);
fill(50,200,255);
ellipse(0,0,10,10);
What does rotate(theta); rotate? What is the relation of rotate and translate?
rotate and translate are acting on the current coordinate system.
i.e. draw actions (rect(), ellipse(), etc...) will apply within a the current coordinate system. where rotate & translate will move the coordinate system.
prior to the block of code you supplied, the current point was translated to the center of the window in order to draw the sun.
pushMatrix() saves that position and then relative to the suns center, "everything" (the coordinate system) is rotated by theta, and "everything" is translated by (50,0) effectively moving the "current point" to the correct position to then draw the earth using ellipse(0,0,10,10).
Note you could probably omit the translate step and use ellipse(50,0,10,10) to get the same visual result, if it were not for the fact that the next code block is dependent on that translate to get the moon position correctly.
Here is an interesting link which explains this in terms of "moving the graph paper";

Resources