Vector math finding coördinate on a plane between two vectors

I am trying to create a three-dimensional tube along a spline. I have the spline coordinates (x1, y1, z1 - x2, y2, z2 - etc.), which you can see in the illustration in yellow. At these points, I need to create circles whose vertices should be connected at a later stadium. The circles should be perpendicular to the "corners" of the two linear spline segments to form a regular tube. Note that segments are kept low for illustration.

[apparently, I am not allowed to post images, so please view the image at this link] http://img191.imageshack.us/img191/6863/18720019.jpg

As far as I can calculate the vertices of each ring at each point of the spline, but they are all on the same plane, i.e. the same. I need them to rotate according to their “legs” (for example, A and B refer to C).

I thought about it and thought about the following:

  • two line segments can be considered as 2 vectors (in illustrations A and B)
  • the angle (in Figure C) is where you need to calculate the vertex ring.
  • I need to find a planar on which all the vertices will be
  • Then I can use this planar (= vector?) To compute new vectors from the center point, which is C
  • and find them x, y, z using the radius * sin and cos

However, I really got confused in the mathematical part of this. I read about a point product, but returns a scalar, which I do not know how to apply in this case.

Can someone point me in the right direction?

[edit] To give a little more information about the situation:

I need to build a buffer with a floating point, which in groups of 3 describe vertex positions and will be connected by OpenGL ES, given another buffer with indices for forming polygons.

To form the shape of the tube, I first created an array of floats that in groups of 3 elements describe control points in three-dimensional space.

Then, together with the variable for segment density, I pass these control points to a function that uses these control points to create a CatmullRom spline and returns this as another array of floats, which are usually in groups of 3-spine spines of catmull.

In each of these vertices, I want to create a vertex ring that can also vary in density (amount of smoothness / vertices per ring).

All previous peaks (control points and those that describe feline alloy) are discarded.

Only the vertices that form the ring rings will be transferred to OpenGL, which, in turn, will connect them to form the last tube.

I can still create a catmullrom spline and create rings at the position of its vertices, however they are all on planes that are at the same angle, instead of following the path of the splines.

[/ edit]

Thanks!

+3
source share
4 answers

Suppose you have a parametric curve, for example:

xx[t_] := Sin[t]; yy[t_] := Cos[t]; zz[t_] := t; 

What gives: alt text

The tangent vector to our curve is formed by derivatives in each direction. In our case

 Tg[t_]:= {Cos[t], -Sin[t], 1} 

The orthogonal plane to this vector comes to the solution of the implicit equation:

 Tg[t].{x - xx[t], y - yy[t], z - zz[t]} == 0 

In our case, it is:

 -t + z + Cos[t] (x - Sin[t]) - (y - Cos[t]) Sin[t] == 0 

Now we find a circle in this plane centered on the curve. ie:

 c[{x_, y_, z_, t_}] := (x - xx[t])^2 + (y - yy[t])^2 + (z - zz[t])^2 == r^2 

Solving both equations, you get the equation for circles:

alt text

NTN!

Edit

And by drawing a lot of circles, you can get a (inefficient) handset:

alt text

Or with a nice 3D graphics library:

alt text

Edit

Since you insist :) here is a program for calculating the circle at the joints.

 a = {1, 2, 3}; b = {3, 2, 1}; c = {2, 3, 4}; l1 = Line[{a, b}]; l2 = Line[{b, c}]; k = Cross[(b - a), (c - b)] + b; (*Cross Product*) angle = -ArcCos[(a - b).(c - b)/(Norm[(a - b)] Norm[(c - b)])]/2; q = RotationMatrix[angle, k - b].(a - b); circle[t_] := (k - b)/Norm[k - b] Sin@t + (q)/Norm[q] Cos@t + b; Show[{Graphics3D[{ Red, l1, Blue, l2, Black, Line[{b, k}], Green, Line[{b, q + b}]}, Axes -> True], ParametricPlot3D[circle[t], {t, 0, 2 Pi}]}] 

alt text

Edit

Here you have a grid constructed by this method. This is not very, IMHO:

alt text

+10
source

You need to look at Fenet's formulas in differential geometry. See Figure 2.1 for an example with a spiral.

Surfaces and Curves

+1
source

I don’t know what your language of choice is, but if you are talking about MatLab, there are already a few implementations available. Even if you use a different language, some of the code may be clear enough to inspire re-implementation.

The key point is that if you do not want your tube to swirl when connecting vertices, you cannot determine the base locally, but you need to propagate it along the curve. The frenet frame proposed by jalexiou is one option, but simpler material works fine.

I made a simple MatLab implementation called tubeplot.m in my developing years (based on the simple distribution of non-Frenet) and googling it, I see that Anders Sandberg from kth.se performed (replay) an implementation with the same name, available at http://www.nada.kth.se/~asa/Ray/Tubeplot/tubeplot.html ,

TubePlot.m illustration

Edit: Below is the pseudo code for a simple implementation in tubeplot.m . I found it to be pretty reliable.

The plan is to extend the two normals a and b along the curve, so that at each point of the curve a , b and the tangent to the curve it forms an orthogonal basis, which is "as close as possible" to the bases used at the previous point. Using this basis, we can find points on the circumference of the tube.

 // *** Input/output *** // v[0]..v[N-1]: Points on your curve as vectors // No neighbours should overlap // nvert: Number of vertices around tube, integer. // rtube: Radius of tube, float. // xyz: (N, nvert)-array with vertices of the tube as vectors // *** Initialization *** // 1: Tangent vectors for i=1 to N-2: dv[i]=v[i+1]-v[i-1] dv[0]=v[1]-v[0], dv[N-1]=v[N-1]-v[N-2] // 2: An initial value for a (must not be pararllel to dv[0]): idx=<index of smallest component of abs(dv[0])> a=[0,0,0], a[idx]=1.0 // *** Loop *** for i = 0 to N-1: b=normalize(cross(a,dv[i])); a=normalize(cross(dv[i],b)); for j = 0 to nvert-1: th=j*2*pi/nvert xyz[i,j]=v[i] + cos(th)*rtube*a + sin(th)*rtube*b 

Implementation Details: You can probably speed things up by calculating cos and sin . In addition, in order to get reliable performance, you must merge the input points closer than, say, 0.1*rtube , or the smallest test that all dv vectors are non-zero.

NTN

+1
source

Taking the transverse product of a line segment and an up vector will give you a vector at right angles to them (unless the line segment is pointing exactly up or down), which I will call horizontal. Taking the transverse product of horizontal and linear segments, you will get another vector that is at right angles to the line segment, and another (let it be called vertical). Then you can get the circular coordinates along the line Start + cos theta * horizontal + sin theta * vertical for theta at 0 - 2Pi.

Edit: To get points for the midpoint between two segments, use the sum of the two segment vectors to find the average.

0
source

Source: https://habr.com/ru/post/1333429/


All Articles