How can I get Tangential direction Vector in Python? - python

I can get some info from a Arc.
FirstPoint   [x, y, z]
LastPoint   [x, y, z]
Center    [x, y, z]
Axis      [x, y, z] # Perpendicular to the plane
How can I get the FirstPoint&LastPoint's tangential direction Vector?
I want to get a intersection Point from two direction vector.
I work in FreeCAD.

Circular arc from A to B with center M and normal vector N.
The tangent directions can be obtained by the cross product.
Tangent at A: N x (A-M)
Tangent at B: (B-M) x N
Both correspond to a rotation of 90DEG or -90DEG of the radius vectors around the axis N

We'll need a lot more information to give a good answer, but here is a first attempt, with questions after.
One way to approximate a tangent vector is with a secant vector: If your curve is given parametrically as a function of t and you want the tangent at t_0, then choose some small number e; evaluate the function at t_0 + e and at t_0 - e; then subtract the two results to get the secant vector. It will be a good approximation to the tangent vector if your curve isn't too curvy in that interval around t.
Now for the questions. How is your question related to Python, and where does FreeCAD come in? You have constructed the curve in FreeCAD, and you want to compute tangents in Python? Can you say anything about the curve, like whether it's a cubic spline curve, whether it curves in only one direction, what you mean by "center" and "axis"? (An arbitrary curve with tangent vectors isn't necessarily a cubic spline, might curve in very complicated ways, and doesn't have any notion of a center or axis.)

s.Curve
Circle (Radius : 1, Position : (0.335157, 11.988, 5.55452), Direction : (-0.914329, -0.257151, 0.312851))
s.Vertex1.Point #FirstPoint
Vector (0.7393506936636021, 11.360676836326173, 6.220155663200929)
s.Vertex2.Point #LastPoint
Vector (0.3602513339713556, 12.723079925995924, 6.232050903393676)
s.Curve.FirstParameter
0.0
s.Curve.LastParameter
6.283185307179586
It's a simple arc.

Related

get 16 equidistant points along the circumference of ellipse

I am trying to get the 16 equidistant point on ellipse (equal arc length along the ellipse).
Using some research, I am able to get the angle from which I can get those point by drawing a straight line and getting the intersection point but unable to find the length of line to be drawn from the center. I have also explored https://math.stackexchange.com/questions/172766/calculating-equidistant-points-around-an-ellipse-arc but getting confused in formula
What is the value of φ here?
Can anyone please help me there on getting the points. Thanks
We can define (axis-aligned) ellipse parametrization as
x = a * cos(φ)
y = b * sin(φ)
where parameter φ has range 0..2*Pi.
Resulting point (x,y) is situated at angle θ relative to the ellipse center. Your linked post shows formula for θ/φ transformation.
Note - θ is real angle, φ is not!, it is just parameter.
You perhaps don't need θ here. To solve the problem, you have to find ellipse circumference length L using elliptic integral for φ = 2*Pi (numerically).
Then find φ values corresponding to arc length L/16, 2*L/16...15*L/16 - numerically again, and calculate corresponding point coordinates from the parametrization equations.

How to format data for matplotlib contour

I am experimenting with gradient descent and want to plot a contour of the gradient given independent variables x and y.
The optimization objective is to estimate a point given only a list of points and the distances to each of those points. I have a list of vectors of form [(x_1, y_1, d_1), ..., (x_n, y_n, d_n)] where d_i is the measured distance from the point to be estimated to the point (x_i, y_i), and I have a function g(x, y) that returns the gradient at the point (x, y). (The function g(x, y) uses the training vectors to calculate the gradient.)
The gradient descent algorithm works fine and arrives at a close estimate to the actual point coordinates. I want now to visualize the gradient as a contour map. I have the following for x and y values:
xlist = np.linspace(min([v[0] for v in vectors])-1, max([v[0] for v in vectors])+1, 100)
ylist = np.linspace(min([v[1] for v in vectors])-1, max([v[1] for v in vectors])+1, 100)
X, Y = np.meshgrid(xlist, ylist)
But now I need a Z value that maps each pair of coordinates in the grid mesh to g(x, y), and it needs to be the correct shape for the matplotlib contour plot. The examples I have seen have been useless because they all simply multiplied the x and y arrays to generate z values (which obviously will not work in this case), and all the tips, tricks, and SO answers I have encountered ultimately did not help.
How do I use my custom function g(x, y) to create the 2D Z array necessary for constructing a valid contour plot?

Sample points from a hyperboloid

A hyperboloid has the formula
-x^2/a^2 - y^2/b^2 + z^2/c^2 = 1.
How can I generate samples from this hyperboloid in Python? (Say, with a=b=c=1.)
I was thinking to pick random x and y in [0,1] and then fill in the z value that would make the formula equal 1. However this would not sample uniformly. Is there a better way?
This is only a partial answer.
J.F. Williamson, "Random selection of points distributed on curved surfaces", Physics in Medicine & Biology 32(10), 1987, describes a general method of choosing a uniformly random point on a parametric surface. It is an acceptance/rejection method that accepts or rejects each candidate point depending on its stretch factor (norm-of-gradient). To use this method for a parametric surface, several things have to be known about the surface, namely—
x(u, v), y(u, v) and z(u, v), which are functions that generate 3-dimensional coordinates from two dimensional coordinates u and v,
The ranges of u and v,
g(point), the norm of the gradient ("stretch factor") at each point on the surface, and
gmax, the maximum value of g for the entire surface.
The algorithm is then:
Generate a point on the surface, xyz.
If g(xyz) >= RNDU01()*gmax, where RNDU01() is a uniform random number in [0, 1), accept the point. Otherwise, repeat this process.
In the case of a hyperboloid with parameters a=b=c=1:
The gradient is [2*x, -2*y, 2*z].
The maximum value of the gradient norm is:2*sqrt(3), if x, y, and z are all in the interval [0, 1].
The only thing left is to turn the implicit formula into a parametric equation that is a function of two-dimensional coordinates u and v. I know this algorithm works for parametric surfaces, but I don't know if it still works if we "pick random x and y in [0,1] and then fill in the z value that would make the formula equal" in step 1.

Find the center of Curvature of a point on 3D b-spline using nurbs / geomdl in python

Once again I am in over my head so please bear with me.
I have a B-spline (imported from Solidworks) that I can analyze with geomdl in python.
From geomdl I can extract the first and second derivatives as well as the tangent, normal, and binormal vectors for any given point on the spline.
From there I can calculate the curvature at that point from the first and second derivatives.
However I am not able to determine which way the curve is turning.
I would like to find the point that is at the center of curvature of current point of interest on the bspline.
I 'think' that the tangent vector and the normal vector both lie on the osculating plane of interest. The cross product would then give me the normal to the osculating plane. However I can not make this work.
At a minimum I need to know which way the curve is bending. i.e. CW or CCW.
But if I have the point at the center of curvature I would know pretty much everything about that point.
Is this correct?
To restate the question:
Given a point, the derivatives of the curve at that point, and and the Tangent, Normal, and BiNormal vectors, how do I find the center of curvature?
Given a parametric curve C(t) and the first and 2nd derivatives C'(t) and C"(t), the curvature vector can be found
K(t) = m1*C"(t) - m2*C'(t)
where
m1 = 1.0/||C'(t)||^2 and m2 = m1*m1 * C'(t) \dot C"(t).
From K(t), you can find the radius of curvature R(t) as
R(t) = K(t)/||K(t)||^2
and then the center of curvature is C(t)+R(t).

Calculating 3D world point

I am beginner in OpenCV and I want to find 3D point from 2D (projected on image) and known two out of three world coordinates of a point.
What I have:
calibrated camera (known: matrix of intrinsic parameters, vector of distortion coefficients)
rotation vector and translation vector
(u, v) - coordinates of a point on image
two known world coordinates of a point and one unknown
Problem variant #1 Known: X, Y Unknown: Z
Problem variant #2 Known: X, Z Unknown: Y
Problem variant #3 Known: Y, Z Unknown: X
How can I find third unknown coordinate? Is it possible?
Yes it is possible. Consider the simple case of absent nonlinear distortion. Let Ki be the inverse of the camera matrix, and camera center at the world origin (i.e. no rotation nor translation). Let p=(u, v, 1) be the homogeneous pixel coordinate. Then the ray through the pixel is:
s * P = Ki * p
where s > 0 is an unknown scale. But s * P = [X, Y, Z], so if you know any one of X, Y or Z you can solve for s and find the missing coordinates.
For non-zero roto-translation, replace Ki with the inverse of the projection matrix. For non-zero distortion, replace the simple multiplication by Ki with the complete reprojection equation.

Categories

Resources