get random number of parameters that satisfy given equation in Python - equation-solving

I'm new to Python and I would like to get 1000 of parameters that satisfy a given equation.
More precisely, below is the equation of the sphere, assume the position of the sphere center(x0, y0, z0) and its radius are both given.
(x - x0)^2 + (y - y0)^2 + (z - z0)^2 = radius^2
How could I randomly generate a number of (x, y, z) that satisfy the sphere equation in python?
Thanks a lot!

One approach would be to take the center point (x0, y0, z0) and add a random vector of length r to it.
Then the question reduces to "how does one create a random vector of fixed length?". One could create a random vector and normalize it to unit length, and then stretch it to have length r.
Hope that helps, and best of luck!

Related

Question about performance for raytracing algorithm intersection test

I'm currently building a basic raytracing algorithm and need to figure out which system of handling the intersections would be best performance-wise.
In the method I'm checking for a intersection of the ray and the object I'm returning a struct with the distance of the ray traveled to the hit, the position vector of the hit and the normal vector or -1 for the distance if there is no intersection.
For the next step I have to find the shortest distance of all intersections and exclude the ones with a negative distance.
I even thought about having 2 structs, one with only negative distances and one full struct to reduce the amount of space needed, but thought this wouldn't really make a difference.
My options so far:
first go over the array of the intersections and exclude the ones with negative distances, then find the shortest distance from the remainings via a sorting algorithm (probably insertion sort due to quick implementation).
Or put them together in one algorithm and test in each sort step if the distance is negative.
typedef Point3f float[3];
typedef struct {
float distance;
Point3f point;
Point3f normal;
} Intersection;
Intersection intersectObject (Ray-params, object) {
Intersection intersection;
//...
if (hit) {
intersection.distance = distance;
intersection.point = point;
intersection.normal = normal;
} else {
intersection.distance = -1.0f;
}
return intersection;
}
//loop over screen pixel
Intersection* intersections;
int amountIntersections;
//loop over all objects
//here I would handle the intersections
if (amountIntersections) {
//cast additional rays
}
I can't really figure out what would be the best way to handle this, since this would be called a lot of times. The intersection array will probably be a dynamic array with the amountIntersections as the length variable or an array with the most expected amount of intersections which then have intersections in it with negative distances.
Here is the approach I've succesfully used for a huge number of objects. (Especially for ball-and-stick atomic models; see my Wikipedia user page for the equations I used for those.)
First, transform the objects to a coordinate system where the eye is at origin, and the projected plane is parallel to the xy plane, with center on the positive z axis. This simplifies the equations needed a lot, as you can see from the above linked page.
As an example, if you have a unit ray n (so n·n = 1) and a sphere of radius r centered at c, the ray intersects the sphere if and only if h ≥ 0,
h = (n·c)2 + r2 - (c·c)
and if so, at distance d,
d = n·c ± sqrt(h)
If you work out the necessary code, and use sensible temprary variables, you'll see that you can reject non-intersecting spheres using eight multiplications and six additions or subtractions, and that this vectorizes across objects easily using SSE2/AVX intrinsics (#include <x86intrin.h>). (That is, do not try to use an XMM/YMM vector register for n or c, and instead use each register component for a different object, calculating h for 2/4/8 objects at a time.)
For each ray, sort/choose the objects to be tested according to their known minimum z coordinate (say, cz - r for spheres). This way, when you find an intersection at distance d, you can ignore all objects with minimum z coordinate larger than d, because the intersection point would necessarily be further out, behind the already known intersection.
Similarly, you should ignore all intersections where the distance is smaller than the distance to the projection plane (which is zd / nz, if the plane is at z = zd, and only needs to be computed once per ray), because those intersections are between the eye and the projection plane. (Technically, you've "crashed into" something then, if you think of the projection plane as a camera.)

Angle to Quaternion - Making an object facing another object

i have two Objects in a 3D World and want to make the one object facing the other object. I already calculated all the angles and stuff (pitch angle and yaw angle).
The problem is i have no functions to set the yaw or pitch individually which means that i have to do it by a quaternion. As the only function i have is: SetEnetyQuaternion(float x, float y, float z, float w). This is my pseudocode i have yet:
float px, py, pz;
float tx, ty, tz;
float distance;
GetEnetyCoordinates(ObjectMe, &px, &py, &pz);
GetEnetyCoordinates(TargetObject, &tx, &ty, &tz);
float yaw, pitch;
float deltaX, deltaY, deltaZ;
deltaX = tx - px;
deltaY = ty - py;
deltaZ = tz - pz;
float hyp = SQRT((deltaX*deltaX) + (deltaY*deltaY) + (deltaZ*deltaZ));
yaw = (ATAN2(deltaY, deltaX));
if(yaw < 0) { yaw += 360; }
pitch = ATAN2(-deltaZ, hyp);
if (pitch < 0) { pitch += 360; }
//here is the part where i need to do a calculation to convert the angles
SetEnetyQuaternion(ObjectMe, pitch, 0, yaw, 0);
What i tried yet was calculating the sinus from those angles devided with 2 but this didnt work - i think this is for euler angles or something like that but didnt help me. The roll(y axis) and the w argument can be left out i think as i dont want my object to have a roll. Thats why i put 0 in.
If anyone has any idea i would really appreciate help.
Thank you in advance :)
Let's suppose that the quaternion you want describes the attitude of the player relative to some reference attitude. It is then essential to know what the reference attitude is.
Moreover, you need to understand that an object's attitude comprises more than just its facing -- it also comprises the object's orientation around that facing. For example, imagine the player facing directly in the positive x direction of the position coordinate system. This affords many different attitudes, from the one where the player is standing straight up to ones where he is horizontal on either his left or right side, to one where he is standing on his head, and all those in between.
Let's suppose that the appropriate reference attitude is the one facing parallel to the positive x direction, and with "up" parallel to the positive z direction (we'll call this "vertical"). Let's also suppose that among the attitudes in which the player is facing the target, you want the one having "up" most nearly vertical. We can imagine the wanted attitude change being performed in two steps: a rotation about the coordinate y axis followed by a rotation about the coordinate z axis. We can write a unit quaternion for each of these, and the desired quaternion for the overall rotation is the Hamilton product of these quaternions.
The quaternion for a rotation of angle θ around the unit vector described by coordinates (x, y, z) is (cos θ/2, x sin θ/2, y sin θ/2, z sin θ/2). Consider then, the first quaternion you want, corresponding to the pitch. You have
double semiRadius = sqrt(deltaX * deltaX + deltaY * deltaY);
double cosPitch = semiRadius / hyp;
double sinPitch = deltaZ / hyp; // but note that we don't actually need this
. But you need the sine and cosine of half that angle. The half-angle formulae come in handy here:
double sinHalfPitch = sqrt((1 - cosPitch) / 2) * ((deltaZ < 0) ? -1 : 1);
double cosHalfPitch = sqrt((1 + cosPitch) / 2);
The cosine will always be nonnegative because the pitch angle must be in the first or fourth quadrant; the sine will be positive if the object is above the player, or negative if it is below. With all that being done, the first quaternion is
(cosHalfPitch, 0, sinHalfPitch, 0)
Similar analysis applies to the second quaternion. The cosine and sine of the full rotation angle are
double cosYaw = deltaX / semiRadius;
double sinYaw = deltaY / semiRadius; // again, we don't actually need this
We can again apply the half-angle formulae, but now we need to account for the full angle to be in any quadrant. The half angle, however, can be only in quadrant 1 or 2, so its sine is necessarily non-negative:
double sinHalfYaw = sqrt((1 - cosYaw) / 2);
double cosHalfYaw = sqrt((1 + cosYaw) / 2) * ((deltaY < 0) ? -1 : 1);
That gives us an overall second quaternion of
(cosHalfYaw, 0, 0, sinHalfYaw)
The quaternion you want is the Hamilton product of these two, and you must take care to compute it with the correct operand order (qYaw * qPitch), because the Hamilton product is not commutative. All the zeroes in the two factors make the overall expression much simpler than it otherwise would be, however:
(cosHalfYaw * cosHalfPitch,
-sinHalfYaw * sinHalfPitch,
cosHalfYaw * sinHalfPitch,
sinHalfYaw * cosHalfPitch)
At this point I remind you that we started with an assumption about the reference attitude for the quaternion system, and the this result depends on that choice. I also remind you that I made an assumption about the wanted attitude, and that also affects this result.
Finally, I observe that this approach breaks down where the target object is very nearly directly above or directly below the player (corresponding to semiRadius taking a value very near zero) and where the player is very nearly on top of the target (corresponding to hyp taking a value very near zero). There is a non-zero chance of causing a division by zero if you use these formulae exactly as given, so you'll want to think about how to deal with that.)

How would you convert X,Y points to Rho,Theta for hough transform in C?

So I am trying to code Hough Transform on C. I have a binary image and have extracted the binary values from the image. Now to do hough transform I have to convert the [X,Y] values from the image into [rho,theta] to do a parametric transform of the form
rho=xcos(theta)+ysin(theta)
I don't quite understand how it's actually transformed, looking at other online codes. Any help explaining the algorithm and how the accumulator for [rho,theta] values should be done based on [X,Y] would be appreciated.Thanks in advance. :)
Your question hints at the fact that you think that you need to map each (X,Y) point of interest in the image to ONE (rho, theta) vector in the Hough space.
The fact of the matter is that each point in the image is mapped to a curve, i.e. SEVERAL vectors in the Hough space. The number of vectors for each input point depends on some "arbitrary" resolution that you decide upon. For example, for 1 degree resolution, you'd get 360 vectors in Hough space.
There are two possible conventions, for the (rho, theta) vectors: either you use [0, 359] degrees range for theta, and in that case rho is always positive, or you use [0,179] degrees for theta and allow rho to be either positive or negative. The latter is typically used in many implementation.
Once you understand this, the Accumulator is little more than a two dimension array, which covers the range of the (rho, theta) space, and where each cell is initialized with 0. It is used to count the number of vectors that are common to various curves for different points in the input.
The algorithm therefore compute all 360 vectors (assuming 1 degree resolution for theta) for each point of interest in the input image. For each of the these vectors, after rounding rho to the nearest integral value (depends on precision in the rho dimension, e.g. 0.5 if we have 2 points per unit) it finds the corresponding cell in the accumulator, and increment the value in this cell.
when this has been done for all points of interest, the algorithm searches for all cells in the accumulator which have a value above a chosen threshold. The (rho, theta) "address" of these cells are the polar coordinates values for the lines (in the input image) that the Hough algorithm has identified.
Now, note that this gives you line equations, one is typically left with figure out the segment of these lines that effectively belong in the input image.
A very rough pseudo-code "implementation" of the above
Accumulator_rho_size = Sqrt(2) * max(width_of_image, height_of_image)
* precision_factor // e.g. 2 if we want 0.5 precision
Accumulator_theta_size = 180 // going with rho positive or negative convention
Accumulator = newly allocated array of integers
with dimension [Accumulator_rho_size, Accumulator_theta_size]
Fill all cells of Accumulator with 0 value.
For each (x,y) point of interest in the input image
For theta = 0 to 179
rho = round(x * cos(theta) + y * sin(theta),
value_based_on_precision_factor)
Accumulator[rho, theta]++
Search in Accumulator the cells with the biggest counter value
(or with a value above a given threshold) // picking threshold can be tricky
The corresponding (rho, theta) "address" of these cells with a high values are
the polar coordinates of the lines discovered in the the original image, defined
by their angle relative to the x axis, and their distance to the origin.
Simple math can be used to compute various points on this line, in particular
the axis intercepts to produce a y = ax + b equation if so desired.
Overall this is a rather simple algorithm. The complexity lies mostly in being consistent with the units, for e.g. for the conversion between degrees and radians (most math libraries' trig functions are radian-based), and also regarding the coordinates system used for the input image.

How to calculate point along a curve?

I am writing a custom animation for wpf and as a non math guy I have a couple questions...
If I am given two Point3D's, the From and To, and assuming the origin is at 0,0,0 how do I calculate a curve between the two points?
And once I have the curve 'plotted' and I know its length (how to do that too?) how can I calculate the x,y,z coords at some given distance along the line?
Thanks!
To get a straight line vector from point A to point B:
B - A
which would translate to:
vector.x = b.x - a.x;
vector.y = b.y - a.y;
vector.z = b.z - a.z;
The length is:
length = Math.Sqrt(vector.x * vector.x +
vector.y * vector.y +
vector.z * vector.z);
To get a point a certain distance along the vector you need to make the vector a unit vector (length 1):
vector.x = vector.x / length;
...
and then multiply by your distance:
vector.x = distance * vector.x;
...
This is all from memory so might not compile straight away.
There's A Vector Type for C# on CodeProject which will do a lot of this for you.
If you want a curve, then you'll need:
a) to define what type of curve you want (arc, spline, etc.)
b) more points (centres, control points etc.)
You'll probably want to express your curve as a set of parametric functions of some other variable:
x = f(t)
y = g(t)
z = h(t)
where 0 <= t <= 1, and
f(0) = from.x, f(1) = to.x
g(0) = from.y, g(1) = to.y
h(0) = from.z, h(1) = to.z
There are an infinite number of curves connecting any two points, so you'll need more
information to decide what form f(t), g(t), and h(t) should take. To move a point
along the curve, you just let t vary between 0 and 1 and calculate the x, y, and z
coordinates. One approach is to define a set of control points that you'd like your
curve to pass through (or near), then express your parametric equations in terms of
spline functions. You won't need to know the arc length of the curve in order to do this.
So I just wanted to follow up with my solution- while it is true there are an infinite number of curves- my (poorly worded) question was how to plot between two points on a curve- the shortest distance, assuming an origin of 0,0,0 and two 3d points. What I did was to convert my points from cartesian to polar, calculate the spherical point at a given time and then convert that point back to cartesians. If anyone wants me to post the actual C# code let me know.

How to find coordinates of a 2d equilateral triangle in C?

I have the coordinates (x,y) of 2 points. I want to build the third point so that these 3 points make an equilateral triangle.
How can I calculate the third point?
Thank you
After reading the posts (specially vkit's) I produced this simple piece of code which will do the trick for one direction (remember that there are two points). The modification for the other case shold be trivial.
#include<stdio.h>
#include<math.h>
typedef struct{
double x;
double y;
} Point;
Point vertex(Point p1, Point p2){
double s60 = sin(60 * M_PI / 180.0);
double c60 = cos(60 * M_PI / 180.0);
Point v = {
c60 * (p1.x - p2.x) - s60 * (p1.y - p2.y) + p2.x,
s60 * (p1.x - p2.x) + c60 * (p1.y - p2.y) + p2.y
};
return v;
}
You could rotate the second point 60° around first to find the location of the third point.
Something like this:
//find offset from point 1 to 2
dX = x2 - x1;
dY = y2 - y1;
//rotate and add to point 1 to find point 3
x3 = (cos(60°) * dX - sin(60°) * dY) + x1;
y3 = (sin(60°) * dX + cos(60°) * dY) + y1;
Let's call your two points A and B. Bisect AB, call this point C. Find the slope of AB (YA-YB / XA-XB), call it m. Find the perpendicular to that (-1/m) and call it m2. Then compute a segment CD whose length is sin(60) * length(AB), at the slope m2 (there will be two such points, one to each side of AB). ABD is then your equilateral triangle.
That, obviously, is a "constructive" method. You should also be able to do it by solving a set of linear equations. I haven't tried to figure out the right system of equations for this case, but this approach tends to be somewhat more stable numerically, and has fewer special cases (e.g., with the constructive version, a slope of 0 has to be dealt with specially).
For BlueRaja's challenge go to end of post:
Answer using translation and rotation:
Says points are P(x1,y1) and Q(x2,y2).
Since it is graphics, you can use tranforms to get the point.
First translate axes so P is the origin.
Next rotate Q around P by 60 degrees (or -60 to get the other possible point).
This gives you the coordinates of the third point say R, when P is the origin.
Translate back and there you have it.
You can use standard graphics API which take care of precision etc issues for you. No headaches.
Of course you could do the math and actually come up with a formula and use that and that might be faster, but then the question might get closed as off-topic ;-)
To take up BlueRaja's challenge: Here is a method which does not use trigonometry.
Given points P(x1,y1) and Q(x2,y2)
Say the point we need (R) to find is (x3,y3).
Let T be midpoint of PQ.
We know the area of triangle PQR (as it is equilateral and we know the side)
and we know the area of triangle PRT (1/2 the earlier area).
Now area of a triangle can be written as a determinant having the co-ordinates as entries:
2*Area = |D|
where
| 1 x1 y1|
D = | 1 x2 y2|
| 1 x3 y3|
We have two such equations (which are linear), solve for x3 and y3.
pc <- c((x1+x2)/2,(y1+y2)/2) #center point
ov <- c(y2-y1,x1-x2) #orthogonal vector
p3 <- pc+sqrt(3/4)*ov #The 3dr point in equilateral triangle (center point + height of triangle*orthogonal vector)

Resources