what i got is a vector line (normalized vector vx,vy some point x0,y0, form fitLine OpenCv) and a rectangle defined by four points (clockwise p1,p2,p3,p4). now i need to know, if the line is going through the rectangle.. which means there need to be two points above (or left from) the line and two points below (or right from) the line. how can i archive this in c++?
This question looks like a homework ;)
First, you will need to discribe your line as an equation (1) such as Ax+By=C. Any basic algebra book will tell you how to do that (or wikipedia).
Then, you will need to find the similar equations for each edge of your rectangle. Let's call those equations (2),(3),(4) and (5).
Then, you will need to find the intersection of (1) with each other equations. Let's call thoses points a , b ,c and d.
Afterward, you will need to figure out for each intersection points if it stands between the appropriate vertexes. If it's the case, they cross a rectangle edge!
If the your line cross at least one edge, you can say that your line cross your rectangle.
Here the challenge is to be able to deal with a line that is parralel to your rectangle or that is directly on one of a rectangle edge. Do not be shy to make yourself a nice drawing to be sure of what you are doing.
The equation of your vector is
y - y0 = (vy/vx) (x - x0)
To tell whether point (x1,y1) is above, on or below the line, solve the line for x1 and compare y to y1.
y > y1 - below
y == y1 - on
y < y1 - above
So compare the your vector to each corner of the rectangle.
Related
I am trying to render an outline using Vulkan's stencil buffers. This technique involves rendering the object twice with the second one being scaled up in order to account for said outline. Normally this is done in 3D space in which the normal vectors for each vertex can be used to scale the object correctly. I however am trying the same in 2D space and without pre-calculated normals.
An Example: Given are the Coordinates I, H and J and I need to find L, K and M with the condition that the distance between each set of parallel vectors is the same.
I tried scaling up the object and then moving it to the correct location but that got me nowhere.
I am searching for a solution that is ideally applicable to arbitrary shapes in 2D space and also somewhat efficient. Also I am unsure if this should be calculated on the GPU or the CPU.
Lets draw an example of a single point of some 2D polygon.
The position of point M depends only on position of A and its two adjacent lines, I have added normals too - green and blue. Points P and Q line on the intersection of a shifted and non-shifted lines.
If we know the adjacent points of A - B , C and the distances to O and P, then
M = A - d_p * normalize(B-A) - d_o * normalize(C-A)
this is true because P, O lie on the lines B-A and C-A.
The distances are easy to compute from the two-color right triangles:
d_p=s/sin(alfa)
d_o=s/sin(alfa)
where s is the desired stencil shift. They are of the course the same.
So the whole computation, given coordinates of A,B,C of some polygon corner and the desired shift s is:
b = normalize(B-A) # vector
c = normalize(C-A) # vector
alfa = arccos(b.c) # dot product
d = s/sin(alfa)
M = A - sign(b.c) * (b+c)*d
This also proves that M lies on the alfa angle bisector line.
Anyway, the formula is generic and holds for any 2D polygon, it is easily parallelizible since each point is shifted independently of others. But
for non-convex corners, you need to use the opposite sign, we can use dot product to generalize.
It is not numerically stable for b.c close to zero i.e. when b,c lines are almost parallel, in that case I would recommend just shifting A by d*n_b where n_b is the normalized normal of B-A line, in 2D it is normalize((B.y - A.y, A.x-B.x)).
Im trying to use Vector2::Dot and Math::Acos to determine whether one gameobject is in front of another. With what I have, I'm able to get whether the first object's forward vector is at a perpendicular angle to second actor's forward vector:
float dotResult = Vector2::Dot(GetForwardDir(), secondActor->GetForward());
float angle = Math::Acos(dotResult);
if(angle <= minAngle)
//do something
Where GetForwardDir() is:
return Vector2(Math::Cos(mRotation), -Math::Sin(mRotation));
However this does not account for where the second actor is relative to the first actor. I don't think Im understanding something here about dotResult and the Acos angle.
How can I use this to get whether the first actor is in front of the second?
You probably want a cross product for this. The dot product will give you a scaled cos for the angle between two vectors. A cross product will give you the sin, which is more useful here.
Basically, make two vectors:
ActorA position + ActorA.Forward vector
ActorA position + (ActorB.position - ActorA.position)
Or, just
ActorA.forward X normalize(ActorB.Position - ActorA.position);
Since you're doing this in 2D, the result will be a scalar. If the sign of the result is positive, then ActorB is within 180º (+- 90º) of ActorA's forward vector, from ActorA's position.
Technically, you're calculating an orthogonal vector, the Z component of which will tell you if the target is in front of or behind the viewer, but the X and Y components of that vector are zero, because orthogonal.
Purists will say that the cross product does not exist in 2D, and they're technically correct, but this is how it's done.
I have two images and and know the position of a point in the first image. Now I want to get the corresponding position in the second image.
This is my idea:
I can use algorithms such as SIFT to match keypoints (as seen in the image)
I know the camera matrix using calibration with e.g. chessboards
Using the 8 point algorithm I calculate the fundamental matrix F
Can I now use F to calculate the corresponding point?
Using fundamental matrix F alone is not enough. If you have a point on one image, you can't find its position on the second image, because it depends not only on configuration of the cameras, but also on the distance from the camera to that point.
This can also be seen from the equation x2^T * F * x1 = 0. If you know x1 and F, then for x2 you get equation x2^T * b = 0, where b = F * x1. This is an equation of a point x2 lying on the line b (points x1, x2 and line b are in homogeneous coordinates). Although you cant find the exact position of the point on the second image, you know that it must lie somewhere on that line.
Hartley and Zisserman have a great explanation these of these concepts in their book Multiple View Geometry in Computer Vision. Be sure to check it out for more details.
I am trying to make a sprite walk towards another sprite,
movement_angle = (atan2((y - target->y),(x - target->x)));
if(isWalkable(game,delta))
{
y -= ((int)(movementspeed)*delta)*sin(((movement_angle)));
x -= ((int)(movementspeed)*delta)*cos(((movement_angle)));
}
I am calculating the angle and adding the values to my x and y cords.
But the movement is not perfect, it does not really follow as I wish, takes weird turns and so on.
It's hard to say exactly what's going wrong from your code, but here are some things you could look at:
To get a vector from a point to target you'll need to subtract target->x by the point's x and target->y by the point's y
At least movement_angle needs to be a floating point number, though you'll likely want to use doubles for all your 3D geometry values
Why bother with trigonometric functions? You want to walk directly from point x, y to target->x, target->y, why not just use a vector, normalize it, and multiply by your movementspeed and delta?
Well you are casting an algebraic result to an int. I think that may be causing your problem.
This is quite complicated to explain, so I will do my best, sorry if there is anything I missed out, let me know and I will rectify it.
My question is, I have been tasked to draw this shape,
(source: learnersdictionary.com)
This is to be done using C++ to write code that will calculate the points on this shape.
Important details.
User Input - Centre Point (X, Y), number of points to be shown, Font Size (influences radius)
Output - List of co-ordinates on the shape.
The overall aim once I have the points is to put them into a graph on Excel and it will hopefully draw it for me, at the user inputted size!
I know that the maximum Radius is 165mm and the minimum is 35mm. I have decided that my base [Font Size][1] shall be 20. I then did some thinking and came up with the equation.
Radius = (Chosen Font Size/20)*130. This is just an estimation, I realise it probably not right, but I thought it could work at least as a template.
I then decided that I should create two different circles, with two different centre points, then link them together to create the shape. I thought that the INSIDE line will have to have a larger Radius and a centre point further along the X-Axis (Y staying constant), as then it could cut into the outside line.*
*(I know this is not what it looks like on the picture, just my chain of thought as it will still give the same shape)
So I defined 2nd Centre point as (X+4, Y). (Again, just estimation, thought it doesn't really matter how far apart they are).
I then decided Radius 2 = (Chosen Font Size/20)*165 (max radius)
So, I have my 2 Radii, and two centre points.
This is my code so far (it works, and everything is declared/inputted above)
for(int i=0; i<=n; i++) //output displayed to user
{
Xnew = -i*(Y+R1)/n; //calculate x coordinate
Ynew = pow((((Y+R1)*(Y+R1)) - (Xnew*Xnew)), 0.5); //calculate y coordinate
AND
for(int j=0; j<=n; j++)//calculation for angles and output displayed to user
{
Xnew2 = -j*(Y+R2)/((n)+((0.00001)*(n==0))); //calculate x coordinate
Ynew2 = Y*(pow(abs(1-(pow((Xnew2/X),2))),0.5));
if(abs(Ynew2) <= R1)
cout<<"\n("<<Xnew2<<", "<<Ynew2<<")"<<endl;
I am having the problem drawing the crescent moon that I cannot get the two circles to have the same starting point?
I have managed to get the results to Excel. Everything in that regard works. But when i plot the points on a graph on Excel, they do not have the same starting points. Its essentially just two half circles, one smaller than the other (Stops at the Y axis, giving the half doughnut shape).
If this makes sense, I am trying to get two parts of circles to draw the shape as such that they have the same start and end points.
If anyone has any suggestions on how to do this, it would be great, currently all I am getting more a 'half doughnut' shape, due to the circles not being connected.
So. Does anyone have any hints/tips/links they can share with me on how to fix this exactly?
Thanks again, any problems with the question, sorry will do my best to rectify if you let me know.
Cheers
Formular for points on a circle:
(x-h)^2+(y-k)^2=r^2
The center of the circle is at (h/k)
Solving for y
2y1 = k +/- sqrt( -x^2 + 2hx +r^2 - h^2)
So now if the inner circle has its center # h/k , the half-moon will begin # h and will stretch to h - r2
Now you need to solve the endpoint formular for the inner circle and the outter circle and plot it. Per x you should receive 4 points (solve the equation two times, each with two solutions)
I did not implement it, but this would be my train of thought...