# How to “stretch” a procedural half-sphere texture on X and/or Y axis

I've implemented an Objective-C function to display the "height" of a half-sphere, with "1.0" being "full-height" and "0.0" being "no-height"

The sphere currently has a few parameters:

• Center (x,y: real coordinates)

These values are currently being drawn in a texture with an independent size, provided that the minimum coordinate is (0,0) and the maximum is (1,1), which could be represented by a mathematical function like f(px, py), where px and py are the points where I want the height of the given half-sphere.

Now, I want to add two more parameters to the sphere, a "x-stretch" and a "y-stretch" (we can call them xs and ys), where I could deform the sphere in the X or Y axis.

The current function is like this (provided that the values of "x", "y" and "r" are known):

• $d(px, py) = \sqrt{(x-px)^2 + (y+py)^2}$ as being the distance from the center to the given point
• $f(px, py) = \sqrt{1 - \frac{d(px, py)}{r}}$ as being the value (from 0.0 to 1.0) of the half-sphere height.

Note that f is only calculated if d is smaller than the radius(r)

I want a way to add xs and ys in the above equations, but I don't really know how to get around that.

If it helps, here's the Objective-C function that "solves" the above problem:

- (CGFloat)sphereValueAtPoint:(NSPoint)point center:(NSPoint)sphereCenter radius:(CGFloat)radius {
CGFloat dist;

dist = sqrt(pow(point.x - sphereCenter.x,2) + pow(point.y - sphereCenter.y, 2));
return(0.0);

}


I've also got a faster, optimized function, but it is not as easy to understand.

EDIT: Note that when xs and ys are both equal to 1.0, no scaling should be done. If either are GREATER than 1.0, the texture is stretched and if they are between 1.0 and 0.0, the texture is compressed. You can assume that xs and ys are always greater than 0.0.

EDIT2: As requested, I'm adding some images for clarification. White is 1.0, Black is 0.0 and the gray is in between (check tooltips).

-
I'm finding it very hard to understand your question. Can you add some diagrams? –  Rahul Jun 9 '12 at 2:27
Thanks for trying. I've added some images. Hope it helps. –  Sergio Moura Jun 9 '12 at 2:42

Your stated formula isn't quite correct, though the code is. Allow me denote the variable point as $(x,y)$ and the center of the hemisphere as $(c_x,c_y)$, as is more usual. The formula for the height of the hemisphere should be $$f(x,y) = \sqrt{1 - \frac{d(x,y)^2}{r^2}} = \sqrt{1 - \frac{(x-c_x)^2}{r^2} - \frac{(y-c_y)^2}{r^2}}.$$ If you want to scale its size by $s_x$ and $s_y$, all you have to do is $$f(x,y) = \sqrt{1 - \frac{(x-c_x)^2}{(s_xr)^2} - \frac{(y-c_y)^2}{(s_yr)^2}}.$$
For what it's worth, you're really modelling an ellipsoid with semi-principal axes of length $x_sr$, $y_sr$, and $1$. The implicit equation of an ellipsoid centered at the origin with semi-principal axes of length $a$, $b$, and $c$ is $$\frac{x^2}{a^2}+\frac{y^2}{b^2}+\frac{z^2}{c^2}=1.$$ Substitute $a$, $b$, $c$ with their desired values, replace $x$ and $y$ by $x-c_x$ and $y-c_y$ to translate the origin, and solve for $f(x,y) = z$, and you get the formula above.
It worked flawlessly. The only change I made is that I first calculate $k = 1 - \frac{(x - c_x)^2}{(s_xr)^2}-\frac{(y - c_y)^2}{(s_yr)^2}$. If that is negative, I return the height field 0.0. If not, I go ahead and return $\sqrt{k}$. Thanks a lot! –  Sergio Moura Jun 9 '12 at 16:14