I was having trouble plotting a horizontal line
...
set arrow 2 from graph 0, y(x) to x, y(x) nohead
...
For clarity, assume that x = 1 => y = 3 So as far as I understood, that should have generated a line from (0,3) to (1, 3). However, the y coordinate of the first point (0,3) turned out to appear somewhere outside the plot. But if I use (according to a post here)
set arrow 2 from graph 0, first y(x) to x, y(x) nohead
then it yields the output I wanted.
Can someone explain to me the magic above using first?
It is worth reading help coordinates to learn about the different coordinate systems. In short, the first coordinate system is that defined by the current ranges of the x and y axes: the bottom left corner of the graph has coordinates (xmin,ymin), and the top right corner has coordinates (xmax, ymax). In the graph coordinate system the bottom left corner is always (0,0) and the top right corner is always (1,1), independent of the ranges of the two axes.
Here is a brief example:
set xrange [-4:4]
set yrange [-3:3]
set grid
set arrow 1 from first 0,0 to first 1,1 ls 1 lw 3
set arrow 2 from graph 0,0 to graph 1,1 ls 2 lw 3
plot 1/0 ti ""
The purple vector is arrow 1, which goes from (0,0) to (1,1) in the first coordinate system. The second vector is arrow 2, which goes from (0,0) to (1,1) in the graph coordinate system.
The default rules for which coordinate system will be used are
If the coordinate system for x is not specified, first is used. If
the system for y is not specified, the one used for x is adopted.
and for the special case of set arrow,
A coordinate system specifier does not carry over from the first endpoint description [to] the second.
It sounds like you want to use the first coordinate system, so you shouldn't have to do anything:
set arrow from 0, y(x) to x, y(x)
When you use
set arrow from graph 0, y(x) to x, y(x)
you use the graph coordinate system for the starting point, and the first coordinate system for the end point.
When you use
set arrow from graph 0, first y(x) to x, y(x)
you use the graph coordinate system for the starting point's x coordinate, and the first coordinate system for the remaining coordinates. If range of the x axis starts at zero, this would be the same as using the first coordinate system for everything.
Related
In a 3D space (x,y,z), you are given two points with no restrictions.
Let's say Point 1 = (15,10,-5), Point 2 = (-1, 0, 11)
An arbitrary point (denoted X in the image) is made by finding the mid-point between point 1 and point 2, in this case (7,5,6), and then y is incremented by 10 which creates a third point
Point 3 = (7,15,6)
Attached is an image to better portray these points
The problem is to find an equation that creates the orange line that links the points 1, 2 and 3. The line doesn't necessarily have to link on the bottom, but I assume it is easier to create an ellipse with these points than an inverse parabola.
It is rather simple to build a circle through these three points (note they must be non-collinear).
Make a plane containing given points, use arbitrary coordinate system in this plane. For example, point P1 is origin, vector P2-P1 defines OX axis, vector product of P2-P1 and P3-P1 defines normal N, and (P2-P1) x N defines OY axis
Solve "circle through three points" problem in this plane, find radius and center.
Transform center back into 3D.
Also note that there is infinite number of ellipses and parabolas through three points (until we define additional limitations),
I'm doing some canvas painting, and for performance reasons I want to get the coordinate of where a straight line enters and/or exits the screen.
To put it more simply, I want to find out the coordinates A' and B' in the illustration below. A and B are the original start- and end coordinates. A' and B' are the coordinates where the straight line from A to B enters or exits the screen bounds.
This seems like something that would be a common scenario, but I can't really find a simple and efficient algorithm for it.
I'm using Flutter, but I guess this is a general problem with a similar solution no matter which language (A and B are points, the screen is a rect).
We are given the following parameters and equations:
points A and B are given by their respective coordinates (xA, yA) and (xB, yB);
the bounding box is given by the 4 inequations xMin <= x; x <= xMax; yMin <= y; y <= yMax;
line (AB) is given by its equation (y-yA)*(xB-xA) = (yB-yA)*(x-A).
We can use them to solve for the intersection points:
In the first two examples, you can find the coordinates (x,y) of A' by setting y=yMax and solving the line equation for x;
In the first example, you can find the coordinates (x,y) of B' by setting x=xMax and solving the line equation for y;
In the third example, you can find the coordinates (x,y) of B' by setting y=yMin and solving the line equation for x.
To find all intersection points with the bounding box in all possible case, you could solve the equations for all 4 possible types of intersections, then discard solutions which either:
do not satisfy the bounding box inequations (those solutions are intersections with the "continuations" of the sides of the bounding box); or
do not satisfy the inequations of the implicit bounding box around segment [AB] (those solutions are intersections of the line (AB) with the bounding box, and of no interest to you if you want only the intersections of the segment [AB] with the bounding box).
I am trying to create a game using one-point perspective. Everything works fine for points within the view but goes wrong with the negative depth. I understand the perspective as shown on the following picture (source).
In general, I took a point at some distance from the left of the right vertical edge of the frame along the lower horizontal line (5 points in this case), join it with the O' point (line H'O') and where the line intersects the vertical line (at point H') is the depth line (of 5 in this case). This works well even for negative depth (as the line H'O' intersect the vertical line below the viewpoint). However, if the depth is more then is the distance of O' (that mean the point would be on the right from the O') the line flip and the H' end on top of the viewpoint (although it should end up below).
How should I correct it, so the point with negative depth is transformed correctly (mean from 3D space to 2D space)?
EDIT
This image is probably better.
My question is how to handle points with negative depth (should end up below the screen) higher then is a distance of transversal.
The points to the right of the point O', along the line determined by the lower edge of the frame, correspond to points that are behind the observer, so technically, the observer cannot see them. To see the points behind you, means that you have to turn around, so you need to change the position of the screen. Draw a copy of the black square frame to the right of the point O', so that the new square is the mirror symmetric image of the original frame square with respect to the line orthogonal to the horizon line and passing trough the point O'.
Edit: The points with negative depth to the right of point O' (i.e. a point behind the observer) is supposed to be mapped above the horizontal blue line. This is the right way to go.
I assume your coordinate system in three dimensions has its origin at the lower right corner of the square frame on your picture. The x axis (I think how you measure width) runs along the lower horizontl edge of the frame, while the y axis (what you call height) is along the right vertical edge of the frame. The depth axis is in three dimensions and it's perpendicular to the plane of the square frame (so it is parallel to the ground). It starts from the lower right corner of the frame square. Assume that the distance of point O' from the right vertical edge of the square is S and the coordinates of the point C are {C1, C2} (C1 is the distance of point C from the right vertical edge and C2 is the distance of C from the lower horizontal edge of the square).
Given the coordinates {w, h, d} (w - width, h - height, d - depth) of a point in three dimensions, its representation on the two dimesnional square screen is gievn by the formulas:
x = (S*w + C1*d)/(S+d)
y = (S*h + C2*d)/(S+d)
So the points you gave as an example in the comments are
P1 = {h = 5, w = 5, d = 5} and P2 = {h = 5, w = 5, d = -10}
Their representation on the screen is
P1_screen = {(S*5 + C1*5)/(S+5), (S*5 + C2*5)/(S+5)}
P2_screen = {(S*5 - C1*10)/(S-10), (S*5 - C2*10)/(S-10)}
whatever your parameters S, C1 and C2 are. The representation of the (infinte) line connecting points P1 and P2 is represented on the screen as the (infinite) line connecting the points P1_screen and P2_screen. However, if you want the 2D representation of the visible part of the segment that connects P1 and P2, then you have to draw the (infinite) line between P1_screen and P2_screen and exclude the following two segment: segment [P1_screen, P2_screen] and the segment from P2_screen along the line up towards the upper top edge. You have to draw on the screen only the segment from the infinite line connecting P1_screen and P2_screen which starts from P1_Screen and goes down towards the lower horizontal edge of the screen.
I have some triangles in 3D space, which originate from 0,0,0 and extend towards two points p1= -x0, 0, z0 and p2= +x0, 0, z0. This is in Unity, such that +z is the forward axis (i.e. they lie flat). Each triangle is its own mesh, pivot is at 0,0,0.
Now, I would like to rotate these (using Quaternion.LookRotation) such that their ends form a continuous polygon, in case of three triangles a triangle, in case of four triangles a square, etc.
My approach is to calculate the incircle radius of the resulting polygon based on the length of each triangle (which is 2*x0). If I now calculate n points on this circle (where n is the number of triangles I have), I get x/y coordinates which I can directly use to set the "up" axis of each triangle correctly, i.e. Quaternion.LookRotation(Vector3.forward, new Vector3(x,y,0)). This orients the triangle correctly around the z axis, i.e. the center is still on 0,0,1.
However, and this has me stumped, I still need to change the forward axis of the triangles such that they tilt to form the final polygon. I tried using new Vector3(x,y,z0) which gives an almost correct result, but leads to an overlap at the edges. I suspect this is somehow due to the fact that rotation of the triangles effectively changes z0, but I am not sure how to proceed.
My question is, how to calculate the new forward axis such that the triangles align properly?
The problem is setting the forward axis to (x,y,z0), which is wrong since the length of the vector (x,y,z0) does not equal the original length (which is just z0). The z value thus needs to be adjusted such that new Vector(x,y,z1).magnitude == z0. This can be done by calculating
Mathf.Sqrt(Mathf.Pow(z0, 2) - Mathf.Pow(x, 2) - Mathf.Pow(y, 2))
Problem solved.
I've always wondered the easiest way to figure out whether or not a point lies within a triangle, or in this instance, a rectangle cut into half diagonally.
Let's say I have a rectangle that is 64x64 pixels. With this rectangle, I want to return a TRUE value if a passed point is within the upper-left corner of the rectangle, and FALSE if it isn't.
-----
| /|
| / |
|<__|
Horray for bad ASCII art.
Anyway, the hypothetical points for this triangle that would return TRUE would be (0,0) and (63,0) and (0, 63). If a point lands on a line (e.g., 50,0) it would return TRUE as well.
Assuming 0,0 is in the upper-left corner and increases downwards...
I've had a possible solution in my head, but it seems more complicated than it should be - taking the passed Y value, determining where it would be in the rectangle, and figuring out manually where the line would cut at that Y value. E.g, a passed Y value of 16 would be quarter height of the rectangle. And thus, depending on what side you were checking (left or right), the line would either be at 16px or 48px, depending on the direction of the line. In the example above, since we're testing the upper-left corner, at 16px height, the line would be at 48px width
There has to be a better way.
EDIT:
The rectangle could also look like this as well
-----
|\ |
| \ |
|__>|
But I'm figuring in most cases the current answers already provided should still hold up...
Top-left/bottom-right triangles: For all points in the top-left triangle, x+y<=64. Points in the bottom-right triangle have x+y>64.
(for a rectangle of size (w,h) use w*y+h*x-w*h<0)
Top-right/bottom-left triangles: For all points in the bottom-left triangle, x<=y. Points in the top-right triangle have x>y.
(for a rectangle of size (w,h) use h*x-w*y<0)
How did we get there?
For a rectangle of dimensions (w,h) and TL/BR triangles, the equation of the diagonal is (try it out! assign x=0 and check that you get y==h, and assign y=0 and check that x==w)
h*x + w*y - w*h = 0
Points on one side of that line will have
h*x + w*y - w*h > 0
While points on the other will have
h*x + w*y - w*h < 0
Inserting 64 for both w and h, we get:
64x + 64y - 64*64 < 0
Dividing by 64 gets us:
x+y < 64
For TR/BL triangles, the line equation and the resulting inequalities are:
h*x - w*y = 0
h*x - w*y < 0
h*x - w*y > 0
Inserting 64 for w and h, we get
64x-64y < 0
=> x<y
you can represent the triangle with three affine functions
take the unit triangle with corners at (0, 0), (1, 0) and (1, 1). the sides are represented by the three lines
y = 0
x = 1
y = x
So the interior and boundry of the triangle are given as the intersection of the sets
x >= 1
y >= 0
y <= x
so given a point, (x, y), you just need to verify that it satisfies those three inequalities.
You can of course generalize this to any triangle using the fact that any affine function (representing a line) can be written in the form y = mx + b.
The equation for the line looks like this :
y = mx + b
So, if you insert your x and y-Values into that equation, it will probably not hold anymore. Let's reformulate it:
mx + b - y = 0
Same thing, different look. Again, the result is probably not zero. But, the result will now tell you whether it's on the one side of the line or the other.
Now you just have to find out whether the point is inside your rectangle.
Lets assume your right angled triangle has one corner at 0,0 and the diagonal corner at a,b.
So y=mx+c c=0 as we start at the origin.
m=b/a
So y=bx/a
To know which half of the triangle your point (c,d) falls in
if (d<=(bc/a)) {//point is in bottom half}
if (d>(bc/a)) {//point is in top half}
I think...
A simple option is to use a ray casting algorithm. Whilst perhaps a little overkill for what you need, it does have the advantage that it will work with more complex triangles and polygons.
Loosely, the algorithm takes an imaginary point in a direction (infinitely off to the left, for example) and casts a ray to your test point; you then calculate whether each line of your triangle crosses that infinitely long line. If you get an odd number of crossings, your point is inside your triangle; even and you're out of your triangle