I need to make a small program that draws three circles, a line between the first two, and then determines if the third touches or intersects the line. I have done everything but the last part. I am trying to use the points to determine if the area is 0, which would mean that the third point is, in fact, intersecting the line. Right? Or I could use another way. Technically the third circle can be within 3 pixels of the line. The problem is near the bottom at the hashtag. I would appreciate any help or suggestions that move this in another direction. Thank you.
import turtle
x1, y1 = eval(input("Enter coordinates for the first point x, y: "))
x2, y2 = eval(input("Enter coordinates for the second point x, y: "))
x3, y3 = eval(input("Enter coordinates for the third point x, y: "))
turtle.penup()
turtle.goto(x1, y1)
turtle.pendown()
turtle.circle(3)
turtle.penup()
turtle.goto(x2, y2)
turtle.pendown()
turtle.circle(3)
turtle.penup()
turtle.goto(x3, y3)
turtle.pendown()
turtle.circle(3)
turtle.penup()
turtle.color("red")
turtle.goto(x1, y1)
turtle.pendown()
turtle.goto(x2, y2)
a = (x1, y1)
c = (x3, y3)
#can't multiply sequence by non-int of type 'tuple'
area = (a * c) / 2
if area == 0:
print("Hit")
else:
print("Miss")
Ther center of 3rd circle is (x3,y3) and have a radius 3 and you are trying to determine any intersection with ([x1,y1],[x2,y2]) line segment.
If any point in the line is within the circle, then there is an intersection.
Circle region formula is: (x-x3)^2 + (y-y3)^2 < 3^2
You should test for every point on the line whether this inequality holds and if any single point satisfies this condition, then you can conclude that the line and circle intersect.
The first step would be to determine coordinate points of line segment (all points between [x1,y1],[x2,y2] points in a straight line) then you can try to test these points in a loop.
You can calculate the area of the triangle by defining vectors from one vertex to the other two (adding a third constant coordinate to embed the plane in 3-dimensional space (so cross-products make sense)),
#pseudocode
b = (x2, y2, 1) - (x1, y1, 1) = (x2-x1, y2-y1, 0)
c = (x3, y3, 1) - (x1, y1, 1) = (x3-x1, y3-y1, 0)
then take the cross-product of these,
a = b cross c = (by*cz-bz*cy, bz*cx-bx*cz, bx*cy-by*cx)
then take the magnitude of this resulting vector which is the area of the parallelogram defined by the two vectors,
pa = |a| = ax^2 + ay^2 + az^2
then divide by two to get the area of the triangle (half of the parallelogram).
ta = pa/2
Source: http://en.wikipedia.org/wiki/Triangle_area#Using_vectors
Am I wright? The position of the circles to each other does not matter?
Make a linear function from the line between the two center points. (ax+b=y)
Where a is the gradient and b is the y-intersection.
To rotate a through 90° is easy. Inverse and negate a.
Find b of the second linear function. b'=y-a'*x .
At once replace the x,y with the coordinates of your 3. circle point.
Now you have a linear function which is rectangular to the old one and where the third circle point is part of.
Intersect the old linear function with the new one.
You'll get the lot point.
You need to find out the distance between the 3. circle point and the lot point and whether it is greater than the radius.
You need there functions (JS):
function makelinear (x1,y1,x2,y2){
var temp=x2-x1;
if(temp==0)temp=0.00000000000001;//not clean but fast.
var a=(y2-y1)/temp,
b=y1-a*x1;
return[a,b];
}
function ninetydeg(a,b,x,y){
var aout=1/a,
bout=y+aout*x;
return [aout,bout];
}
function lineintersection(a1,b1,a2,b2){
var temp=a1-a2;
if(temp==0)temp=0.00000000000001;
var x=(b2-b1)/temp,
y=a1*x+b1;
return[x,y];
}
function distance(x1,y1,x2,y2){
var x=x1-x2,
y=y1-y2;
return(Math.sqrt(x*x+y*y));
}
Sorry for to be complicate, I've found no other solution in short time. May be there is a vector solution.
Related
I am trying to determine a players depth position on a plane, which defines the walkable ground in a 2D brawler game. The problem is depictured in the following drawing:
C represents the players current position. I need to find the magnitude of vector V. Since I am not strong on linear algebra, the one thing I can think of is: determining the intersection point P of L1 and L2, and then take the magnitude from AP. However, I get the feeling there must be an easier way to find V, since I already know the angle the vector should have, given by vector from AB.
Any input would be appreciated, since I am looking forward to step up my linear algebra game.
Edit: As it is unclear thanks to my lack of drawing skills: the geometry depicted above is a parallelogram. The vector V I am looking for is parallel to the left and right side of the parallelogram. Depth does not mean, that I am looking for the vector perpendicular to the top side, but it refers to the fake depth of a purely 2D game. The parallelogram is therefore used as a means for creating the feeling of walking along a z axis.
The depth of your player (length of V) as measured from the top line in your drawing, is just the difference between A.y and C.y. This is seperate from the slant in the parralelogram, as we're just looking at depth.
example:
float v;
Vector2 a = new Vector2(100, 100); //The point you're measuring from
Vector2 c = new Vector2(150, 150); //Your character position
v = c.y - a.y; // This is the length of V.
//In numbers: 50 = 150 - 100
Illustrated: image not to scale
This works for any coördinate in your plane.
Now if you'd want to get the length of AC is when you'd need to apply some pythagoras, which is a² + b² = c². In the example that would mean in code:
Vector2 a = new Vector2(100, 100);
Vector2 c = new Vector2(150, 150);
float ac1 = Mathf.Sqrt(Mathf.Pow(c.x - a.x, 2) + Mathf.Pow(c.y - a.y, 2));
Now that is quite a sore to have to type out every time, and looks quite scary. But Unity has you covered! There is a Vector method called Distance
float ac2 = Vector2.Distance(a, c);
Which both return 70.71068 which is the length of AC.
This works because for any point c in your area you can draw a right angled triangle from a to c.
Edit as per comment:
If you want your "depth" vector to be parallel with the sides of the paralellogram we can just create a triangle in the parallelogram of which we calculate the hypotenuse.
Since we want the new hypotenuse of our triangle to be parallel to the parallelogram we can use the same angle θ as point B has in your drawing (indicated by pink in mine), of which I understood you know the value.
We also know the length of the adjacent (indicated in blue) side of this new triangle, as that is the height we calculated earlier (c.y - a.y).
Using these two values we can use cosine to find the length of hypotenuse (indicated in red) of the triangle, which is equal to the vector V, in parallel with the parallelogram.
the formula for that is: hypotenuse = adjacent/cos(θ)
Now if we were to put some numbers in this, and for my example I took 55 for the angle θ. It would look like this
float v = 50/(cos(55));
image not to scale
Let's call the lower right vertex of the parallelogram D.
If the long sides of the parallelogram are horizontal, you can find magnitude of V vector by:
V.magnitude = (c.y - a.y) / sin(BAD)
Or if you prefer:
V.magnitude = AB.magnitude * (c.y - a.y)/(b.y - a.y)
I have a surface Z on a X-Y grid for which I want to find the intersection point with a line. I used so far this code for finding the intersection:
x_ray = x_source + t * x_dir
y_ray = y_source + t * y_dir
z_ray = z_source + t * z_dir
height_above_plane = #(t) z_source + t * z_dir - interp2(X, Y, Z, ...
x_source + t*x_dir, y_source + t*y_dir)
t_intercept = fzero(height_above_plane, 0);
my problem is that when my surface is "wiggly", the function has several zero crossing points, and I want to find the minimal out of them.
How can I do that?
Thanks
A possible approach is to project the ray onto the XY domain and draw the corresponding Bresenham line. As you go along this line, grid cell per grid cell, you will compute the Z altitudes along the ray and check if their range overlaps the range of altitudes of the surface (i.e. the min and max value in this cell).
If yes, you have to find the 3D intersection between the ray and the interpolating surface, an hyperbolic paraboloid. If the intersection does fall inside the grid cell considered, you are done. Otherwise, continue the march along the ray.
Convert the surface to matlab mesh, then use this code.
I am in need of an idea! I want to model the vascular network on the eye in 3D. I have made statistics on the branching behaviour in relation to vessel diameter, length etc. What I am stuck at right now is the visualization:
The eye is approximated as a sphere E with center in origo C = [0, 0, 0] and a radius r.
What I want to achieve is that based on the following input parameters, it should be able to draw a segment on the surface/perimeter of E:
Input:
Cartesian position of previous segment ending: P_0 = [x_0, y_0, z_0]
Segment length: L
Segment diameter: d
Desired angle relative to the previous segment: a (1)
Output:
Cartesian position of resulting segment ending: P_1 = [x_1, y_1, z_1]
What I do now, is the following:
From P_0, generate a sphere with radius L, representing all the points we could possibly draw to with the correct length. This set is called pool.
Limit pool to only include points with a distance to C between r*0.95 and r, so only the points around the perimeter of the eye are included.
Select only the point that would generate a relative angle (2) closest to the desired angle a.
The problem is, that whatever angle a I desire, is actually not what is measured by the dot product. Say I want an angle at 0 (i.e. that the new segment is following the same direction as the previous`, what I actually get is an angle around 30 degrees because of the curvature of the sphere. I guess what I want is more the 2D angle when looking from an angle orthogonal from the sphere to the branching point. Please take a look at the screenshots below for a visualization.
Any ideas?
(1) The reason for this is, that the child node with the greatest diameter is usually follows the path of the previous segment, whereas smaller child nodes tend to angle differently.
(2) Calculated by acos(dot(v1/norm(v1), v2/norm(v2)))
Screenshots explaining the problem:
Yellow line: previous segment
Red line: "new" segment to one of the points (not neccesarily the correct one)
Blue x'es: Pool (text=angle in radians)
I will restate the problem with my own notation:
Given two points P and Q on the surface of a sphere centered at C with radius r, find a new point T such that the angle of the turn from PQ to QT is A and the length of QT is L.
Because the segments are small in relation to the sphere, we will use a locally-planar approximation of the sphere at the pivot point Q. (If this isn't an okay assumption, you need to be more explicit in your question.)
You can then compute T as follows.
// First compute an aligned orthonormal basis {U,V,W}.
// - {U,V} should be a basis for the plane tangent at Q.
// - W should be normal to the plane tangent at Q.
// - U should be in the direction PQ in the plane tangent at Q
W = normalize(Q - C)
U = normalize(Q - P)
U = normalize(U - W * dotprod(W, U))
V = normalize(crossprod(W, U))
// Next compute the next point S in the plane tangent at Q.
// In a regular plane, the parametric equation of a unit circle
// centered at the origin is:
// f(A) = (cos A, sin A) = (1,0) cos A + (0,1) sin A
// We just do the same thing, but with the {U,V} basis instead
// of the standard basis {(1,0),(0,1)}.
S = Q + L * (U cos A + V sin A)
// Finally project S onto the sphere, obtaining the segment QT.
T = C + r * normalize(S - C)
I was wondering if anyone can help me. I'm trying to modal an oval room, and the joists run parallel to one another at 400mm intervals, starting and finishing 200mm from the apexes of the oval. The central joist falls on the centre of the oval at (0,0).
So the oval is positioned at angle = 0, with a centre of (0,0). The major axis is 6000mm long in the x-direction and the minor axis is 3500mm long in the y-direction. The joists run in the y-direction too.
I need to find out the node for each joist along the outside edge of the ellipse. So obviously, I know the x values will be -2800, -2400, ..., 0, ..., 2000, 2400, 2800, and that the central joist will have one node at (0, 1750) and one at (0, -1750), but how can I find the y values for all the other x co-ordinates?
Many thanks.
p.s. In case you can't tell I have exceedinly rudimentary MATLAB skills.
It's convenient to work with semi-axes, denoted a and b below. The equation of ellipse is (x/a)^2+(y/b)^2=1, which gives two values of y, positive b*sqrt(1-(x./a)^2) and negative b*sqrt(1-(x./a)^2).
In MATLAB you can compute them this way:
a = 6000/2;
b = 3500/2;
x = -2800:400:2800;
yP = b.*sqrt(1-(x./a).^2);
yN = - yP;
So, yP contains the positive y-coordinates and yN contains negative y-coordinates.
The dots in front of arithmetic operations mean they are performed on vectors componentwise.
How is possible to detect if a 3D point is inside a cone or not?
Ross cone = (x1, y1, h1)
Cone angle = alpha
Height of the cone = H
Cone radius = R
Coordinates of the point of the cone = P1 (x2, y2, h2)
Coordinates outside the cone = P2( x3, y3, h3)
Result for point1 = true
Result for point2 = false
To expand on Ignacio's answer:
Let
x = the tip of the cone
dir = the normalized axis vector, pointing from the tip to the base
h = height
r = base radius
p = point to test
So you project p onto dir to find the point's distance along the axis:
cone_dist = dot(p - x, dir)
At this point, you can reject values outside 0 <= cone_dist <= h.
Then you calculate the cone radius at that point along the axis:
cone_radius = (cone_dist / h) * r
And finally calculate the point's orthogonal distance from the axis to compare against the cone radius:
orth_distance = length((p - x) - cone_dist * dir)
is_point_inside_cone = (orth_distance < cone_radius)
The language-agnostic answer:
Find the equation of the line defining the main axis of your cone.
Compute the distance from the 3D point to the line, along with the intersection point along the line where the distance is perpendicular to the line.
Find the radius of your cone at the intersection point and check to see if the distance between the line and your 3D point is greater than (outside) or less than (inside) that radius.
A cone is simply an infinite number of circles whose size is defined by a linear equation that takes the distance from the point. Simply check if it's inside the circle of the appropriate size.
Wouldn't it be easier to compute angle between vector to center of cone and vector from apex pointing at point under evaluation. If vector projection is used and the length of the resultant vector is shorter then the vector pointing at the center of the cone the between the angle and length you know if you are inside a cone.
https://en.wikipedia.org/wiki/Vector_projection