I am trying to create a graph calculator and making it display the graph correctly on a "canvas". When I load the HTML file and write x e.g it starts from the upper left corner and goes down to the lower right corner. So the problem is that it displays the graph upside down and it does not include negative values.
I know that the canvas starts from (0,0) in pixel value in the upper left corner and ends at (300,300) in the lower right corner. I want it to display something like the green canvas from this link: http://www.cse.chalmers.se/edu/course/TDA555/lab4.html
points :: Expr -> Double -> (Int,Int) -> [Point]
points exp scale (x, y) = [(x, realToPix (eval exp (pixToReal x))) | x<-[0..(fromIntegral canWidth)] ]
where
pixToReal :: Double -> Double --converts a pixel x-coordinate to a real x-coordinate
pixToReal x = x * 0.02
realToPix :: Double -> Double --converts a real y-coordinate to a pixel y-coordinate
realToPix y = y / 0.02
You're probably used to working with 2D coordinate systems where positive y is up, but as you noted in HTML canvas positive y goes down. To simulate the coordinate system you want, you need to flip all the y-values over the line y=0 (aka the x-axis).
Here are a few y-values and their corresponding corrections you can use as tests. Note that I'm assuming y has already been scaled properly; it looks like you've already got that part.
150 -> 0
0 -> 150
-150 -> 300
The pattern is y_new = -(y_old - 150) where 150 is canvas_height/2. Therefore, after scaling you need to apply this formula to all your y values.
To shift the y-axis to the center you need to do the same sort of thing to derive the appropriate linear transformation.
Related
In this ActionScript reference on the atan2 function, it reads:
Computes and returns the angle of the point y/x in radians, when
measured counterclockwise from a circle's x axis (where 0,0 represents
the center of the circle). The return value is between positive pi and
negative pi. Note that the first parameter to atan2 is always the y
coordinate.
For example
Math.atan2(0.7071, -0.7071)
(note that the first parameter is the Y coordinate) returns 2.356, which is positive Pi*3/4.
But in Flash graphics the Y axis goes down, not up. Shouldn't it be "clockwise" instead?
This is the general description of what the atan2 function does in all programming languages.
With that said, you have to indeed put atan(-dy,dx) to get the counter-clock wise angle in screen coordinates, or atan2(dx,dy) to get the zero angle pointing upwards.
I've been trying to work with more complicated shaders, and have run into issues with the coordinate systems used by the vertex shader and texture sampler. In short: they don't seem to make any sense, and when trying to test them I end up getting inconsistent results. To make matters worse, the internet has little in the way of documentation, and most of the information I've found seems to expect me to know how this works already. I was hoping someone could clarify the following:
The vertex shaders pass an (x, y, z) representing a location on the render target. What are acceptable values for x, y, and z?
How do x and y correspond to the width and height of the back buffer (assuming that it's the render target)?
How do x and y correspond to the width and height on an output texture (assuming that it's the render target)?
When x=0 and y=0 where does the vertex sit, location-wise?
The texture samplers sample a texture at a (u, v) coordinate. What are acceptable values for u and v?
How do u and v correspond with the width and height of the texture being sampled?
How do AGAL's wrap, clamp, and repeat flags alter sampling, and what is the default behavior when one isn't given?
when sampling at u=0 and v=0, which pixel is returned location-wise?
EDIT:
From my tests, I believe the answers are:
Unsure
-1 is left/bottom, 1 is right/top
Unsure
At the center of the output
Unsure
0 is left/bottom, 1 is right/top
Unsure
The far bottom-left of the texture
You normally use the coordinate system of your own and then multiply the position of each vertex by MVP (model-view-projection) matrix to get NDC coordinates that can be fed to GPU as an output of vertex shader. There is a nice article explaining all that for Stage3D.
Correct. And z is in range [0, 1]
Rendering to a render target is the same as rendering to backbuffer - you output NDC from your vertex shader so the real size of the texture is irrelevant.
Yup, center of the screen.
Normally, it`s [0, 1] but you can use values that go out of that range and then the output depends on texture wrap mode (like repeat or clamp) set on the sampler.
(0, 0) is left/top, (1, 1) is right/bottom.
Default one is repeat. Those modes decide what you will get when you sample using coordinate that is out of range of [0, 1]. With repeat [1.5, 1.5] will result in [0.5, 0.5] while [1.0, 1.0] will be the result if the mode is set to clamp.
Top-left pixel of the texture.
I have data like this
x-axis data values
-20.49, -12.23, -9.99, -1.00 0 , 1.12, 2.23, 3.45, 4.56, 8.99, 20.99, 30.23
y-axis data values
10,20,20,40,50,60........
I would like to transform above given data into xy coordinate system.
Please have look at the image.
For eg:
along x-axis (min, max ) data value (-20.49, 30.23),
along y-axis (min, max ) data value (10,60)
now if I want plot data(-20.49, 10) in image,
the X coordinate is going to be =200,
and Y-coordinate going to be = 220.
Like this I want plot all data fits within the range of rectangle.
Hope this gives all details
Thanks
This is more of the math question, not related to any programming language. And speaking about Actionscript 3, it has Y axis going from top to bottom, not from bottom to top. Anyway: If you have two points on an axis that you want to map to screen coordinates of your choice, record xmin as lesser native value, xmax as greater native value, and coordinates as xleft and xright. Then, when you need to receive a screen coordinate for your given x, you calculate the xcoord value as:
xcoord = xleft + (x - xmin)*(xright - xleft)/(xmax - xmin);
Similar approach will net you correct values for the Y axis.
I need to get the coordinates of all the pixels inside this particular region of an ellipse.
I know the size of the grid, the center of the elipse and the vertical_radix and horizontal_radix.
I searched on the math forums but couldn't find anything useful.
So for the next example the grid is 26 by 26.
Center of the ellipse is at (13, 7) and vertical_radix is 7 and horizontal_radix = 13.
Knowing this I need the coordinates (pair of x and y) of all the grey pixels.
I just need like a function that knowing this 6 params (grid_width, grid_height, x_center, y_center, vertical_radix, horizontal_radix) could get my coordinates. (any of the tagged languages)
Thanks.
Scale the x and y offsets of the dots from the center into a unit circle, then check the distance from the center.
EDIT:
Assuming a center of (x, y), a point at (x1, y1), and an ellipse with axes of (a, b):
The scaled point is (2(x1-x)/a, 2(y1-y)/b). See if this is more or less than 1 from (0, 0), i.e. square each component and compare the sum with 1.
I am creating a 3D sphere gallery with ActionScript 3 and the Flash 10 3D (2.5D) APIs. I have found a method that works but is not ideal. I would like to see if there is a better method.
My algorithm goes like this:
Let n = the number of images
h = the height of each image
w = the width of each image
Approximate the radius of the circle by assuming (incorrectly) that the surface area of the images is equal to the surface area of the sphere we want to create.To calculate the radius solve for r in nwh = 4πr2. This is the part that needs to be improved.
Calculate the angle between rows. rowAngle = 2atan(h / 2 / r).
Calculate the number of rows.rows = floor(π / rowAngle).
Because step one is an approximation, the number of rows will not fit perfectly, so for presentation add padding rowAngle.rowAngle += (π - rowAngle * rows) / rows.
For each i in rows:
Calculate the radius of the circle of latitude for the row.latitudeRadius = radius * cos(π / 2 - rowAngle * i.
Calculate the angle between columns.columnAngle = atan(w / 2 / latitudeRadius) * 2.
Calculate the number of colums.columns = floor(2 * π / columnAngle)
Because step one is an approximation, the number of columns will not fit perfectly, so for presentation add padding to columnAngle.columnAngle += (2 * π - columnAngle * column) / column.
For each j in columns, translate -radius along the Z axis, rotate π / 2 + rowAngle * i around the X axis, and rotate columnAngle * j around the Y axis.
To see this in action, click here. alternate link. Notice that with the default settings, the number of items actually in the sphere are less by 13. I believe is the error introduced by my approximation in the first step.
I am not able to figure out a method for determining what the exact radius of such a sphere should be. I'm hoping to learn either a better method, the correct method, or that what I am trying to do is hard or very hard (in which case I will be happy with what I have).
I would divide this problem into two connected problems.
Given a radius, how do you pack things on to the sphere?
Given a number of things, how do you find the right radius?
If you have a solution to the first problem, the second is easy to solve. Here it is in pseudo-code.
lowerRadius = somethingTooSmall
fittedItems = itemsForRadius(lowerRadius)
while fittedItems < wantedItems:
lowerRadius *= 2
fittedItems = itemsForRadius(lowerRadius)
upperRadius = 2 * lowerRadius
while threshold < upperRadius - lowerRadius:
middleRadius = (upperRadius + lowerRadius)/2
if itemsForRadius(middleRadius) < wantedItems:
lowerRadius = middleRadius
else:
upperRadius = middleRadius
This will find the smallest radius that will pack the desired number of things with your packing algorithm. If you wish you could start with a better starting point - your current estimate is pretty close. But I don't think that an analytic formula will do it.
Now let's turn to the first problem. You have a very reasonable approach. It does have one serious bug though. The bug is that your columnAngle should not be calculated for the middle of your row. What you need to do is figure out the latitude which your items are in that is closest to the pole, and use that for the calculation. This is why when you try to fit 10 items you find a packing that causes the corners to overlap.
If you want a denser packing, you can try squishing rows towards the equator. This will result in sometimes having room for more items in a row so you'll get more things in a smaller sphere. But visually it may not look as nice. Play with it, and decide whether you like the result.
BTW I like the idea. It looks nice.
In the case of squares, it seems to be an approximate formula for knowing the relationship between the radius, the square's side and the number of squares embedded.
Following this, the number of squares is:
Floor[4 Pi/Integrate[(x^2 + y^2 + r^2)^(-3/2), {x, -a/2, a/2}, {y, -a/2, a/2}]]
or
Floor[(Pi r)/ArcCot[(2 Sqrt[2] r Sqrt[a^2+2 r^2])/a^2]]
where
r = Radius
a = Square side
If you plot for r=1, as a function of a:
Where you can see the case a=2 is the boundary for n=6, meaning a cube:
Still working to see if it can be extended to the case of a generic rectangle.
Edit
For rectangles, the corresponding formula is:
Floor[4 Pi/Integrate[(x^2 + y^2 + r^2)^(-3/2), {x, -a/2, a/2}, {y, -b/2, b/2}]]
which gives:
Floor[(2 Pi r)/(Pi-2 ArcTan[(2 r Sqrt[a^2+b^2+4 r^2])/(a b)])]
where
r = Radius
a,b = Rectangle sides
Let's suppose we want rectangles with one side half of the other (b = a/2) and a sphere of radius 1.
So, the number of rectangles as a function of a gives:
Where you may see that a rectangle with a "large" side of size 2 allows 10 rectangles in the sphere, while a rectangle of "large" side 4 allows only 4 rectangles.