I have two lines (L1, L2) in 3D.
L has the following starting and ending coordinates : P1(x1, y1, z1) and P2(x2, y2, z2).
L2 has P3(x3, y3, z3) and P2(x2, y2, z2). Notice how both L1's and L2's P2 are same: meaning they intersect at this specific point.
Now I want to find a point P(x,y,z) at any distance from P2 that line (P,P2) is perpendicular to plane on which points (P1,P2,P3) are placed.
The cross product is the way of calculating perpendicularity relative to your two lines. You need to make vectors of your line parameters, simples way would be this:
vecL1 = (x1-x2, y1-y2, z1-z2) and
vecL2 = (x3-x2, y3-y2, z3-z2)
Cross product you can google how to calculate, but in this scenario:
//Replacing the new x,y,z's with i, j, k to avoid naming confusion.
vecL3 = vecL1 x vecL2 = (j1*k2 - j2*k1, k1*i2 - k2*i1, i1*j2 - j1*i2)
Now the cross product per definition is a new vector (line) that is strictly perpendicular to the two lines/vectors you used to calculate this with. But vectors lack position, so you need to add the intersection point to this vector in order to find some point.
//i3, j3, k3 being the third vector's parameters
P3(i3+x2, j3+y2, k3+z2)
PS: The distance from your P2 to P3 is per definition (how cross products work) to the area of a parallelogram that the two lines are sides of, I found a link to illustrate:
Normalizing the 3rd vector will make the distance equal to 1 from P2.
The cross product will give you a perpendicular vector to the plane described by two other vectors, in pseudo-code:
normal = cross(normalize(P1-P2), normalize(P3-P2))
Since you've defined P2 as the point of intersection, you can simply add this normal vector to P2 to get your perpendicular point.
If you have any line AB then an arbitrary point C will always be perpendicular to AB IFF triangle ABC has no angle larger than π/2
That means there will always be a point D on line AB such that CD is perpendicular to AB
Related
I'm trying to find if two line segments intersects in 3D space. Both segments are given by points (x1, y1, z1) and (x2, y2, z2). The following artcile describes how to do it in 2D space: https://www.geeksforgeeks.org/check-if-two-given-line-segments-intersect/ but I have no clue how to distinguish points orientation in 3D space (if they are clockwise or counter-clockwise). Thanks in advance.
Calculate direction vectors d1 and d2 for both segments (d1.x = x12-x11 and so on, where x11 is starting point of the first segment, x12 is ending point)
Calculate starting points difference (b.x = x21 - x11 and so on)
Find
p = (d1 x d2) (vector product)
If p is zero vector, then lines are parallel.
If lines do intersect, (b.dot.p) should be = 0 (scalar product), else these lines are skew.
Intersection point:
ip = point11 + d1 * [ (b x d2).dot.p / (p.dot.p) ]
Note that value in [] should be in range 0..1, otherwise lines intersect outside of segments.
Seems similar approach is described in wiki
I have X-Y plane and points (xi, yi) where x, y and i are integers. Now if I draw infinite lines of slope 1 and -1, I have to find those 2 points which either will lie on the same line or if none of them lie then should output:
Case : If atmost 1 point lies on a line the 2nd point should be the point which has minimum distance from the line. In such cases we can draw the line exactly between those 2 points to minimize the distance.
I am not able to find the solution to this problem. My approach was to look at the points in opposite quadrants but I did not get any solution better than O(n^2).
First, I would transform the points into a different coordinate system that is rotated by 45°:
u = x + y
v = x - y
If the original points lie on a line with slope 1, their v coordinate will be equal. If they lie on a line with slope -1, their u coordinate will be equal.
Now, create two lists of points. One sorted by u, the other sorted by v. Then iterate all the points. To find the point that is closest to the corresponding line, you just have to check the neighbors in the sorted order. If there are neighbors with the same u/v coordinate, you are done. If not, find the neighbor with the smallest u/v difference and remember it. Do this for all the points and report the pair with the smallest distance.
I can not put questions in one line also here they are:
How to draw a curve which is part of the circle(depending on the end point)
Let:
p1=(x1,y1) be the first point
have to be line p2=(x2,y2) is the starting point of drawing the curve
p3=(x3,y3) be the end point (mouse location)
Requirements:
if P3 is going closer to p2, the larger the potential radius becomes
p3 describes the drawing direction
if p3 is pararel to p2 there nothing should be drawn (or drawn line p3>p2)
if p3 is equal to p1 it should draw a relatively large wheel,
EDIT:
I think i found solution how to draw that part of circle, please look at that gifs below:
Tangent A->B implies a normal-line Q that passes through the (as-yet unfound) circle center D
Find the midpoint M of chord R (i.e., segment B-C).
A line S perpendicular to R passing through M also passes through D
So: Construct lines Q and S and find their intersection D. The length of segment B-D is the radius of the circle. With the radius and center D you should be able to calculate the arc B->C.
in b4 9000 hours in mspaintpaint.net
I have a set of points in 3d. I form a line by joining these points. I have to obtain another line which is a shifted version of this line, such that the resultant shift is always to the right of the original line. What would be an approach to solve this problem? How to get the up vectors in the right direction each time?
Assume these points to lie on a sphere. Looking at the top view of the sphere i would want something like this
/\/\/\/\
/\/\/\/\
The first line is the original set of points and the second one the shifted set
Ok i am adding the code
std::vector<osg::Vec3> vertArray; // The array containig the 3d points
std::vector<osg::Vec3> shiftVec; // The array to store the shifted vectors
osg::Vec3 line1, line2, result, upVec, p1, p2, cross1, cross2;
result = vertArray[1] - vertArray[0];
result.normalise();
result = result X upVec; // i am not sure how to get this upvec for general set of points
shiftVec.push_back(result);
for(unsigned int i = 1; i < vertArray.size() - 1; i++)
{
line 1 = vertArray[i-1] - vertArray[i];
line 2 = vertArray[i+1] - vertArray[i];
line1.normalise();
line2.normalise();
upVec = line1 X line2;
line 1 = line1 X upVec;
p1 = vertArray[i-1] + line1;
line 2 = line2 X upVec;
p2 = vertArray[i+1] + line2;
cross1 = upVec;
cross2 = (p2-p1)X line2
float factor = cross2.lenght()/cross1.length();
result = p1+line1*factor;
result = result - vertArray[i];
shiftVec.push_back(result);
}
result = vertArray[i] - vertArray[i-1];
result.normalise();
result = result X upVec; // i am not sure how to get this upvec for general set of points
shiftVec.push_back(result);
look here: ECEF <-> ENU coordinates this might help
I rather use NEH local North,East,Height(or altitude) coordinate system
it is similar to compass + altimeter
if you are not looking in rotation axis direction (ECEF Z-axis) ... on poles
then North vector is just (0,0,6356754.7)-viewer_position (all in ECEF)
East,West vectors can be obtained as North x (0,0,6356754.7)
don`t remember if it is east or west (depends on your coordinate system and cross multiplicants order)
just check it visually and if wrong reverse the order or negate result
Up vector (Height or Altitude) is easy from this just Up=North x East or Up=North x West
again if wrong direction reverse order or negate result ...
[Notes]
6356754.7 [m] is earths polar radius
if you viewing from poles (ECEF Z-axis)
then North vector and Up vector lies on the same axis (in opposite direction)
which means there is no east or west (singularity)
on south hemisphere is usually used South instead of North
in that case South = (0,0,-6356754.7)-viewer_position
If you three points are A, B and C. Then the three point define a plane. In general the points will not lie on a (straight) line. If they do then it becomes ambiguous what "right" means. If everything is on a sphere, then the three points will define a curve formed by the intersection of the sphere and the plane. You could form another line my finding the intersection of the sphere with a parallel plane.
I'm not quite sure what you want but I'm guessing you want the second line to lie in a parallel plane. You can find the normal to the plane by taking the cross product N=(A-B) X (C-B). It looks like you are doing something like this but you need the ^ operator. See https://www8.cs.umu.se/kurser/TDBD12/VT04/lab/osg/html/doc++/osg/Vec3.html#DOC.2.224.21
upVec = line1 ^ line2;
i have a 3d world where i have several 2d circles laying on the ground facing to the sky.
how can i check if a line will intersect one of those circles frop top-to-down?
i tried to search but all i get is this kind of intersection test:
http://mathworld.wolfram.com/Circle-LineIntersection.html
but its not what i need, here is image what i mean:
http://imageshack.us/m/192/8343/linecircleintersect.png
If you are in a coordinate system, where the ground is given by z = c for c some constant, then you could simply calculate the x, y coordinates of the line for z = c. Now for a circle of origin x0, y0 and radius R, you would simply check if
(x - x0)^2 + (y - y0)^2 <= R^2.
If this is true, the line intersects the circle.
In a 3D sense you are first concerned with not with a circle but with the plane where the circle lies on. Then you can find the point of intersection between the ray (line) and the plane (disk).
I like to use homogeneous coordinates for point, planes and lines and I hope you are familiar with vector dot · and cross products ×. Here is the method:
Plane (disk) is defined by a point vector r=[rx,ry,rz] and a normal direction vector n=[nx,ny,nz]. Together they form a plane W=[W1,W2]=[n,-r·n].
Line (ray) is defined by two point vectors r_A=[rAx,rAy,rAz] and r_B=[rBx,rBy,rBz]. Together they form the line L=[L1,L2]=[r_B-r_A, r_A×r_B]
The intersecting Point is defined by P=[P1,P2]=[L1×W1-W2*L2, -L2·W1], or expanded out as
P=[ (r_B-r_A)×n-(r·n)*(r_A×r_B), -(r_A×r_B)·n ]
The coordinates for the point are found by r_P = P1/P2 where P1 has three elements and P2 is scalar.
Once you have the coordinates you check the distance with the center of the circle by d=sqrt((r_p-r)·(r_p-r)) and checking d<=R where R is the radius of the circle. Note the difference in notation between a scalar multiplication * and a dot product ·
If you know for sure that the circles lie on the ground (r=[0,0,0]) and face up (n=[0,0,1]) then you can make a lot of simplifications to the above general case.
[ref: Plucker Coordinates]
Update:
When using the ground (with +Z up) as the plane (where circles lie), then use r=[rx,ry,0] and n=[0,0,1] and the above intersection point simplifies to
r_p = [ rBy-rAy, rAx-rBx, 0] / (rAy*rBx-rAx*rBy)
of which you can check the distance to the circle center.