We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I have a P3D sketch with a Sphere primitive at 0,0,0. Surrounding the sphere (though not touching) are a number of cubes that are orientated so their z-axis points to the center of the sphere.
The sphere is textured with an image file. How would I go about finding the colour on the surface of the sphere at the point a line from each cube to 0,0,0 intersects the surface ?
looking for general ideas at this stage... was thinking collision detection,raytracing... but also wondered (hoping!) if there may be a simpler method ?
cheers, mala
Answers
It would help to see your entire code
On general I would recommend screenX and screenY and then use get(mouseX,mouseY) and compare to a color of a cube you stored
Anyway when this poses problems (eg when using lights()) you can also use an invisible PGraphics
Hi Chris,
I think you've got the wrong end of stick (vector) ;)
I'm trying to get the colour (RGB) of the texture at specfic point on the surface of the sphere. This point is defined by the intersection of a line between the center of any of the cubes and the sphere's surface. (quick sketch in a 3d program attached)
I use the method you mention to pick the actual cubes when I want to select those for another function.
Hope that makes it a bit clearer ? Cheers, mala
One approach is to not use the sphere primitive -- instead, implement your own sphere texture using e.g. textureSphere example -- now you can know what any given point on the sphere is -- you could for example cache those values in an array while rendering, or do a lookup.
See also this very old thread discussing Toxi annd various iterations of "generic code for drawing a textured sphere"
Thanks Jeremy,
I have come across that example when trying to figure out my texture transparency question here:
https://forum.processing.org/two/discussion/27787/set-transparency-of-texture-image-on-sphere-primitive-p3d
my most recent comment there in large part explains what I'm trying to do here ( not sure if I should cut/paste it here too?)
I need to look at the texturesphere code and try to understand it properly. One thing that is not immediately obvious to me, is the UV mapping (projection) method used in that example, presuambly the world32k image uses Equirectangular projection.
Cheers, mala
If you are curious about how
setTexture()
works in Processing P3D (openGL), here it is:Based on these two related threads, one possible approach is that you could use the cubes as an interface to sampling a 2D PImage. Position the cube with spherical coordinates, then transform those coordinates to a lookup on the original 2D PImage.
Downsides of this approach -- it could get tricky around the poles -- you need to be sampling / projecting in exactly the same way that the sphere renderer did.
https://en.wikipedia.org/wiki/Equirectangular_projection
Exactly. And because the source image in OPs example is not itself an equirectangular projection -- it looks like a photo of a tree, un-projected -- its top and bottom rows won't already be a single pixel value, and so an off-by-1 error in sampling the source image by indicating areas near the top and bottom of the sphere could (potentially) give a dramatically different color result than what displayed on the sphere using setTexture().
Thanks guys. The photo on the example sketch was a bad choice, seems to be the only I have that is not mapped properly! here's the enviro hdr exported to jpeg :
They should all be 2:1 ratio, equirectangular and the enviro textures are usually quite small pixel dimensions, which actually helps me. I'm not trying to map 1 for 1 a pixel to a light.There are only 150 or so lights, hence mentioning averaging the area of the texture as well.
@Jeremy In terms of your suggestion, The cubes are already distrubuted a final fixed position and rotation, there is a cube/light at exactly the top pole but not one at the bottom. Your suggestion to transform the cubes position from spherical coords to lookup on the original image is interesting but what happens when the sphere/image is rotated ?... I'm guessing that could be accounted for ? but I'm already lost before I've started.
can't you just say colGet=get(mouseX,mouseY);
then you just treat what's visible as 2D and get the color
additionally you can use if(dist(mouseX,mouseY, circleX, circleY)<diameter) to use get only when mouse is really on the spere
It needs to be automated really, rather than making the user manually pick with the mouse for every sample required of the map.
re:
I take it you mean ambient 3D lighting. Do you want the cube value to be the pixel value of the texture image pre-lighting, or post-lighting?
This has really gotten far into territory where an MCVE would help us help you better.
@ Jeremy Thanks for your patience.
There are no lights in my P3D sketch, so kinda pre-lighting ;)
This example has camera with nav, all cubes in their positions and a primitive sphere with a texture, the sphere can be rotated and the cubes can be selected, though nothing will happen with the cubes other than a hightlight. Hover over a cube and you get it's ID scribbled in top left corner.
Code is stripped down but still quite a bit : // // LMB + drag to move around globe // LMB double click to reset view // RMB click over a node to select ( in this example won't do anything other than highlight it for now // RMB double click to deselect all nodes // LEFT/RIGHT Arrow keys to rotate globe around it's Y axis // UP/DOWN Arrow keys to rotate globe around it's X axis //
Cheers, mala
I've got this to work a bit, but there's still a problem at poles I think... and I've had to bodge some values, very much trial and error.
You can rotate the globe around Y using LEFT /RIGHT arrow keys and the cubes should update.
I think the position & rotation values of my cubes are not helping, from what I've been told the phi & theta angles I have used to set the rotation of the cubes (so they face to globe center ) are derived wrongly. But any other way I do it they rotate around their Z axis which I don't want.
Anyway code above is now updated :)
This is just some random thought, but couldnt you use ColGet = get(width/2,height/2) in conjunction with rotating the sphere with a rotation around the axis corresponding the hit, so that the hit point would be set at the wanted position and rotating it back? Just like when trying to rotate something around a non origin point? Like if the point you want is at 110, 0,0 you could just rotate the sphere by 90° around the y axis like rotateY(radians(90)) and then get(width/2, height/2) and rotate back rotateY(-radians(90)). This works even if the shape has an unknown rotation, since the point youre looking for would still be at 110,0,0. Now you'd only need to get the corresponding maths behind it. But that would probably be easier to figure out (its basically just the opposite of dragging a sphere(Shape) to rotate it, dont know the math behind it, though)^^. Still, might just be completely wrong^^.
Edit: actually for rotateY, you could do this : rotateY(x * (90/110) - y * ((90/110) * 2)) Thus if it was 110, 0,0 it would end up with 110(90/110) - 0((90/110)*2) = 90 (note, im not sure if its actually -90, but then just add- before the whole equation) and with lets lay 135° rotation, so, 55, -55, 0 its 135°.) its basically the same for the other ones, but i dont know if all 3 in conjunction really get what you need... well, anyway, hope it helps at least a bit^^ Btw, i just noticed you dont want the z axis, so this approach should definetly work, at least i think so^^ (4th edit... Actually you only need the rotateY if you dont have points on other z positions than 0 anyway. so in code it would be something like this :