2
$\begingroup$

I am rendering multiple-views of an object placed at the center of the hemisphere(with known center C and radius R). I would like to know how to compute camera 3d locations and corresponding Euler rotations on hemisphere pointing at the center. An example which shows the possible camera positions is like in the below figure(cameras on hemisphere surface pointing object in the center) enter image description here

Is there any blender-python API or script available for this?

Thank you!

$\endgroup$
7
  • $\begingroup$ Find making a simple dolly is an easy way to do this See blender.stackexchange.com/a/130456/15543 and lots of ways covered here blender.stackexchange.com/a/176762/15543 The orbit is another great way to match lat long while moving a great circle orbit, eg equator, dateline. Check out all the other answers on these links too for a method to suit. @RobinBetts for example re Using the verts of the hemisphere. 50-50 Will leave for other reviewers: possible dupe? blender.stackexchange.com/questions/130404/… $\endgroup$
    – batFINGER
    Commented Feb 1, 2021 at 10:00
  • $\begingroup$ Just to clarify: do you want to calculate camera positions, or do you want to create renders, and calculating camera positions is just your idea of the best way to realize this goal? en.wikipedia.org/wiki/XY_problem $\endgroup$ Commented Feb 1, 2021 at 22:52
  • $\begingroup$ Thanks for asking. I am not asking an indirect question. My direct goal: I want to calculate the camera locations and corresponding Euler rotations(fof camera pointing at the center) on the surface of the (hemi)sphere (like shown in the image I have attached) $\endgroup$
    – akes
    Commented Feb 2, 2021 at 11:09
  • $\begingroup$ @MarkusvonBroady below is script to compute locations on sphere theta is elevation angle and phi is azimuthal angle. thetas = np.linspace(0, math.pi, 20) phis = np.linspace(0, 2*math.pi, 20) thetas = np.linspace(0, math.pi, 20) phis = np.linspace(0, 2*math.pi, 20) r = 1 points = [] for phi in phis: for theta in thetas: x = r * math.sin(theta) * math.cos(phi) y = r * math.sin(theta) * math.sin(phi) z = r * math.cos(theta) points.append([x, y, z]) So, now I have locations(x,y,z), theta & phi. How to compute euler rotations using these? $\endgroup$
    – akes
    Commented Feb 2, 2021 at 17:33
  • $\begingroup$ Thetas and phis ARE your rotations. Or rather numpy arrays of rotations. If they represent rotations from the center, based on which you position the camera, then in order to make the camera look back at the center, you need to mirror its rotation, by adding 180 degrees to it. $\endgroup$ Commented Feb 2, 2021 at 20:10

1 Answer 1

2
$\begingroup$

First let's make sure I understand. A hemisphere:

1

Center of the hemishpere selected (yellow):

2

Center is known (let's start with (0, 0, 0), default 3D cursor position)

Radius is known (let's start with 1 m, default sphere setting)

And you want to compute camera 3d locations and corresponding Euler rotations on hemisphere pointing at the center:

3

(here computed based on current frame)

In order to get this effect, create a UV sphere in default 3D cursor position and default sphere settings, resize the camera to fit inside the hemisphere and make it show in front:

4

On the above screenshot you see 3 pink fields - those have drivers. If you right click on the first field (x location) and choose Add driver, or hover over it and press SHIFT + D, a driver dialog will appear. You can then remove the default variable:

5

And put sin(frame/100) into an expression. Sine will give you a horizontal ratio of the distance for a given angle. Here the angle is frame/100, so the current frame number, divided by 100, expressed in radians (without dividing, the animation would be too quick).

6

Likewise for z location you want cos(frame/100), where cosine will give you a vertical ratio of the distance.

The camera should also rotate towards the middle. So here you want to do the reverse of the above, to calculate the angle based on the ratios. So for Y rotation you input atan2(x, z), but here you're using two variables, that unlike frame, have to be added as input variables.

7

Press Add Input Variable button, choose its type as Transform Channel, name the variable x, point to the camera as the object you're taking the value from, and choose the property of the object you take the value from. Then repeat the same for z (with adequate changes).

You're done. If you parent the camera to the hemisphere, you will be able to scale it, and it will still work. However the rotation will break:

8

This is because I didn't tell you to change the space for two variables in the rotation driver from default World Space to Local Space.

9

If you don't want to use parenting, you can just multiply the ratio you get from sin/cos by the distance (here multiplying was redundant as we would be multiplying by 1, which was the default radius of the sphere). You can hardcode the distance, or use a variable like the (hemi)sphere scale:

10

If you want each frame to correspond to 1°, then you have to replace frame/100 with frame * pi / 180. If you don't want for the camera to start at the top, but at the bottom, you can just subtract 90 from the frame.

Finally, you can add offsets based on sphere position (again, if you didn't use parenting), as well as its rotation, but as you can see below, it gets quite complex really fast without parenting:

11

12 13 14

Location X: sin((frame-90)*pi/180+rotY) * scale + x

Location Z: cos((frame-90)*pi/180+rotY) * scale + z

Rotation Y: atan2(x1-x2, z1-z2)

$\endgroup$
7
  • $\begingroup$ Thank you for the response. I am actually looking for blender-python script solution because I need to generate a list of camera locations and euler rotations and then use the to render one by one. $\endgroup$
    – akes
    Commented Feb 1, 2021 at 15:27
  • $\begingroup$ This is a python script solution, those are python scripted expressions. I don't think i'll have time to extend my question today, but basically inside your script you will use bpy.data.objects["Camera"].location.x = sin(angle_degrees*pi/180) * r + center_x and so on - so you basically copy paste the formulas in the answer. $\endgroup$ Commented Feb 1, 2021 at 15:53
  • $\begingroup$ Thanks @Markus von Broady. I am not much familiar with blender, I do not understand about 'parenting'. All I need is a list of random locations and euler rotations on the hemisphere surface for a given radius and center. I have few questions about your comment: 1. what is 'rotY'? is this the angle? 2. I think the equations given in your answer works for semi-circle. Is the 'rotY' angle which makes gives different semi-circles on hemisphere? Thanks! $\endgroup$
    – akes
    Commented Feb 1, 2021 at 19:08
  • $\begingroup$ rotY is simply the rotation you copy from the hemisphere. By default, it's 0 and you don't have to worry about it. But if the hemisphere gets rotated, you need it to adjust camera to move it accordingly - unless it's parented to the hemisphere, then Blender does it for you - and that's the whole purpose of parenting. $\endgroup$ Commented Feb 1, 2021 at 21:32
  • $\begingroup$ Thanks for clarification and your effort to make me understand. I still have few questions related to below answers: Location X: sin((frame-90)*pi/180+rotY) * scale + x Location Z: cos((frame-90)*pi/180+rotY) * scale + z Rotation Y: atan2(x1-x2, z1-z2) - how to compute Location Z? Rotation around X? Rotation around Z? and in rotation around Y, is x1, x2 and z1,z2 are two points on x and z respectively?? $\endgroup$
    – akes
    Commented Feb 1, 2021 at 21:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .