I want to get the values of pixels in a circumference in an image, and plot them.
I know Circumference is C=2*pi*radius, but I am uncertain about how to iterate through all the points in a circle to get the pixel data.
To get a single pixel, this would work. But I need to get pixel values along a circles circumference. how should I iterate through to get that data?
$pixel=getPixel($image, $x, $y);
look at answers here 3D sphere boundary
it is 3D equivalent of your problem so it may help but if you need also the pixel order to be right then most likely is this not for you.
If you want speed use Bresenham
but for newbies it can be difficult to implement and even more to understand
if you want simplicity instead (or for start) then:
use parametric circle equation
x=x0+r*cos(t)
y=y0+r*sin(t)
which get you pixel position for the circle boundary while t= <0,2*pi) [rad] use deg or rad according to your sin,cos functions
pixels only
circle circumference is 2*pi*r [pixels] so step for parameter t should be small enough to reach as many points
dt <= 2*pi/2*pi*r // whole circle / number of pixels
dt <= 1/r // let use half of that for safety
so for extracting points use this C++ code:
int x0=...,y0=...,r=...; // input values
int xx=x0+r+r,yy=y0,x,y;
double t,dt=0.5/r;
for (t=0.0;t<2.0*M_PI;t+=dt)
{
x=x0+int(double(double(r)*cos(t)));
y=y0+int(double(double(r)*sin(t)));
if ((xx!=x)&&(yy!=y)) // check if the coordinates crossed pixel barrier
{
xx=x; yy=y;
// here do what you need to do with pixel x,y
}
}
if there are holes inside your perimeter then lower the dt more. The less it is the smaller step you use but it also slows down the whole thing. You can have r as double or has its copy to avoid 2 int/double conversions. xx,yy are last used pixel coordinates to avoid processing single pixel multiple times.
At start it is set point that is not inside circle for safety. if r==0 then you should set dt to some safety value like dt=M_PI;
One way to do this would be to copy the low level code used to plot the pixels when creating the image of a circle on the screen. This works by incrementing (or decrementing) one of the co-ordinates and then adjusting the other one so as to keep the same distance from the centre of the circle. To ensure it is symmetrical, you make sure that each octant of the circle is plotted in exactly the same way. Details at http://www.asksatyam.com/2011/01/bresenhams-circle-algorithm_22.html (Or http://en.wikipedia.org/wiki/Midpoint_circle_algorithm of course).
Related
I believe I need a solution using PHP for the following problem. Let's start and say we have a map, that width is 100000 and height 100000.
I'd have a region into that map, designed by many X / Y / Z coordinates. something like:
{{-56000;190073;-4509};{-54955;190073;-4509};{-54954;190638;-4509}{-56000;190638;-4509}}
That's 4 points forming a square on our map. But the zones can be defined by 10+ points, so nothing like squares.
Now I'd need a way to generate N different random coordinates that are INSIDE that region.
I don't know where and how to start with this problem, but I know how to use PHP. Just actually lacking the theory part. What algorithm could I use?
Use the rand function to generate x & y coordinates n the range specified by your bounds:
$x = rand($min_x, $max_x);
$y = rand($min_y, $max_y);
I'm not sure what range you want to use for your z coordinate.
I've managed over the past few months to teach myself PHP, PDO & SQL, and have built a basic dynamic website with user registration/email activation/ and login logout functionality, following PHP/SQL best practices. Now I'm stuck on the next task...
I've created a huge dataset of squares/polygons (3 million+), each 1 minute of latitude & longitude in size, stored in a PHP array with a single set of coordinates (the top left corner). To extrapolate a square-like shape, I simply add 0.016 degrees (~1 minute) to each direction and generate the other 3 coordinates.
I now need to check that each polygon in said array is over at least some portion of land in the United States.... i.e. if one were to produce a graphical output of my completed data set and take a look at the San Fransisco coastline, they'd see something like this.
It's similar to the point-in-polygon problem, except it's dealing with another polygon instead of a point, the other polygon is a country border, and I'm not just looking at intersections. I want to check if:
A polygon/square intersects with the polygon. (Think coastline/border).
A polygon/square is inside the polygon. (Think continental U.S.).
A polygon/square contains part of the polygon. (Think small island).
This is illustrated with my crudely drawn image:
If it matches any of these three conditions, I want to keep the square. If it does not interact with the big polygon in anyway (i.e. it's over water), discard it.
I was thinking the big polygon would be a shapefile of the U.S., that or a KML file which I could strip the coordinates out of to create a very complex polygon from.
Then, I thought I'd pass these matching squares and square ID's over to a csv file for integration into a MySQL table containing a set of coordinates of each square (in fact, I'm not even sure of the best practices for handling tables of that size in MySQL, but I'll come to that when need be). The eventual goal would then be to develop a map using Google Maps API via Javascript to display these squares over a map on the website I'm coding (obviously only showing squares within the viewpoint to make sure I don't tax my db to death). I'm pretty sure I'd have to pass such information through PHP first, too. But all of that seems relatively easy compared to the task of actually making said data set.
This is obviously something that cannot be done by hand, so it needs automating. I know a bit of Python, so would that be of help? Any other tips on where to start? Someone willing to write some of the code for me?
Here is a solution that will be efficient, and as simple as possible to implement. Note that I do not say simple, but as simple as possible. This is a tricky problem, as it turns out.
1) Get U.S. polygon data using Shapefiles or KFL, which will yield a set of polygon shapes (land masses), each defined by a list of vertices.
2) Create a set of axis aligned bounding box (AABB) rectangles for the United States: one for Alaska and each Alaskan island, one for each Hawaiian island, one for the Continental United States, and one for each little island off the coast of the Continental U.S. (e.g., Bald Head Island in N.C., Catalina off the coast of California). Each bounding box is defined as a rectangle with the corners which are the minimum and maximum latitude and longitude for the shape. My guess is that there will be a few hundred of these. For example, for Hawaii's big island, the latitude runs 18°55′N to 28°27′N, and the longitude runs 154°48′W to 178°22′W. Most of your global lat/long pairs get thrown out at this step, as they are not in any of those few hundred bounding boxes. For example, your bounding box at 10°20'W, 30°40'N (a spot in the Atlantic Ocean near Las Palmas, Africa) does not overlap Hawaii, because 10°20'W is less than 154°48′W. This bit would be easy to code in Python.
3) If the lat/long pair DOES overlap one of the several hundred AABB rectangles, you then need to test it against the single polygon within the AABB rectangle. To do this it is strongly recommended to use the Minkowski Difference (MD). Please thoroughly review this website first:
http://www.wildbunny.co.uk/blog/2011/04/20/collision-detection-for-dummies/
In particular, look at the "poly versus poly" demo halfway down the page, and play with it a little. When you do, you will see that when you take the MD of the 2 shapes, if that MD contains the origin, then the two shapes are overlapping. So, all you need to do then is take the Minkowski Difference of the 2 polygons, which itself results in a new polygon (B - A, in the demo), and then see if that polygon contains the origin.
4) There are many papers online regarding algorithms to implement MD, but I don't know if you'll have the ability to read the paper and translate that into code. Since it is tricky vector math to take the MD of the two polygons (the lat/long rectangle you're testing, and the polygon contained in the bounding box which overlapped the lat/long rectangle), and you have told us that your experience level is not high yet, I would suggest using a library that already implements MD, or even better, implements collision detection.
For example:
http://physics2d.com/content/gjk-algorithm
Here, you can see the relevant pseudo-code, which you could port into Python:
if aO cross ac > 0 //if O is to the right of ac
if aO dot ac > 0 //if O is ahead of the point a on the line ac
simplex = [a, c]
d =-((ac.unit() dot aO) * ac + a)
else // O is behind a on the line ac
simplex = [a]
d = aO
else if ab cross aO > 0 //if O is to the left of ab
if ab dot aO > 0 //if O is ahead of the point a on the line ab
simplex = [a, b]
d =-((ab.unit() dot aO) * ab + a)
else // O is behind a on the line ab
simplex = [a]
d = aO
else // O if both to the right of ac and to the left of ab
return true //we intersect!
If you are unable to port this yourself, perhaps you could contact either of the authors of the 2 links I've included here--they both implemented the MD algorithm in Flash, perhaps you could license the source code.
5) Finally, assuming that you've handled the collision detection, you can simply store in the database a boolean as to whether the lat/long pair is part of the United States. Once that's done, I have no doubt you will be able to do as you'd like with your Google Maps piece.
So, to sum up, the only difficult piece here is to either 1) implement the collision detection GJK algorithm, or alternatively, 2) write an algorithm that will first calculate the Minkowski Difference between your lat/long pair and the land polygon contained within your AABB and then secondly see if that MD polygon contains the origin. If you use that approach, Ray Casting (typical point-in-a-polygon solution) would do the trick with the second part.
I hope this gives you a start in the right direction!
I think this other question answers a good portion of what you are trying to do
How do I determine if two convex polygons intersect?
The other portion is that if you are using a database, I would load in all polygons near your view point from both sets (the set of the map polygons and the set of other polygons you generated) and then run the above algorithm on this smaller set of polygons and you can generate a list of all polygons in your set that should be overlayed on the map.
I have an application that has about one hundred users. We have a calender view in which every user can have multiple entries. Every entry of the same user should have the same color, but different users should have different colors. At the moment we have manually defined about 25 colors in an array, and the color a user gets is determined by
$color = $colors[$userid % count($colors)];
We don't want to manually add colors for every new user, and selecting a color for each user seems a bit tedious too.
Is there a simple function to map a number (the users id) to a color (preferably RGB)? The next question that rises is; Is there a way to limit the function to a certain types of colors (ie. only colors in which white letters are readable)?
I don't have a solution, per se, but a suggestion.
First, since you want each user's colors to be unique but random, you could get started with some kind of numerical hash function. That gets you a random number that's most likely unique. if your hash function is decent and your users are in the hundreds that should suffice.
Now you need to turn that into colors, preferably on the dark end of the spectrum. If you go with RGB, You need three numbers. To keep them dark, lets say you keep the total or R, G and B under 200. That's a guess, of course, but it should be pretty dark. Pick a random number [index] between 1 and 3 - that's the R, G or B you're going to start with. Get a number between 0 and 200, and set record it for color[index1]. Now pick one of the remaining indexes, 1-3. For this, pick a number between 0 and color[index1] that you already have. Set the remaining number to 200-color[index1]-color[index2]. Now you have a randomish RGB value that should contrast with white.
I realize I never got much use from that hash function up front - maybe ditch it and just use the userid as a random(seed).
You want to work in the hue-saturation-lightness or hue-saturation-value (HSL or HSV) space.
http://en.wikipedia.org/wiki/HSL_and_HSV
Start by defining some colors based on hue and saturation, and set the lightness to the highest tolerable level that makes the text readable.
Then you can fix the hue and saturation for these colors and decrease the lightness.
So say you started by choosing 25 tolerable colors with different hues and maximum/minimum tolerable lightness.
To generate a color for an index you pick the base color to start with base = id % 25 You then decrease the luminance depending on the index within that color index = (Math.floor(id/25)). Set the luminance somewhere within the tolerable luminance range based on that value. So let's say we will have 5 luminance values per color, set the luminance to
lightness = maxLightness - index*(maxLightness / 4*minLightness)
This simply varies the lightness for each color. You can choose to vary saturation and hue slightly if you would prefer. Converting between HSV and RGB is a well documented procedure.
PHP HSV to RGB formula comprehension
Is it possible to generate this kind of random curves?
I've tried IMagick bezier curves (see http://www.php.net/manual/en/function.imagickdraw-bezier.php), but even with 20-30 points they do not look like this. Here is my sample http://mechanicalzilla.com/sandbox/imagick/curve.php
Thank you.
I bet you could write an algorithm which would basically take x number of random twists before going straight to the exit coordinates. This also assumes that algorithm is smart enough to check the angle of the turn. (assuming you don't want to endup in knot-web)
However, assuming that this isn't your graduation task or that you are paid on per-hour basis to work on this, this would be a waste of time and success is highly doubtful.
Even if you'd manage to generate single line algorithm, doing it so that the lines wouldn't come too close to each other is close to impossible. You will end up with something like this:
Looks like:
x = 0; y = 0; angel = 0;
while (true) {
angel = angel + 0.5 - random(1);
x1 = x + 0.1 * cos(angel);
y1 = y + 0.1 * sin(angel);
if (abs(x1 - x) + abs(y1 - y) < 10)
drawline(x,y,x1,y1);
x = x1; y = y1;
if (x < 0) x = width;
if (y < 0) y = height;
if (x > width) x = 0;
if (y > height) y = 0;
}
This is far from a complete answer, but in my mind's eye seems like it could help you:
Instead of drawing curves from the start to the end point of the entire line, consider subdividing your board into a evenly spaced grid. Each square of one column of the grid is entitled to have one point of one curve in it, and you'd steadily advance from left to right (at first? for simplicity's sake.).
The randomness would come into play by picking a square for a curve - to prevent it from getting too chaotic, you could give this randomness bounds, say, "you're not allowed to pick a square that (if a distance from square to square is considered 1) violates abs(current vertical position - new vertical position) <= 5 unless none such is free anymore at this point" or some other arbitrary restraint. ("unless none such is free anymore at this point" is important, otherwise it's possible to lock yourself into an unsolvable state.)
(Sorry, drawing curves with my mouse -> worst/no interpolation ever. Catmull-Rom interpolation will probably be your friend here, though, I imagine.)
The display should be loose enough given that your curve points cannot arbitrarily scatter together given a grid, but it's probably very difficult to get the curve to connect to the end point 'fluidly' - might be a good solution if you don't mind arbitrary end points, though, read as, the algorithm can decide for itself where it wants the line to end.
Think this idea might help you with your curves?
One way to approach this would be to first generate a set of random curves and then use a physics solver to apply repulsion forces between them to avoid clumping.
Here's a quick proof of concept:
I created this using a very niche tool (for anyone interested: Kangaroo Physics solver, a plugin for Grasshopper, visual scripting language for Rhinoceros3d) but you can probably recreate the same concept in any mainstream programming language, eg. Python.
I'm looking for a way to sort images as in the following screenshot:
http://www.pixolution.de/sites/LargeImages_en.html
I've looked at all the threads on this topic on stackoverflow but none of the proposed solutions even come close to giving me the image above.
Approaches I've tried:
for each image, build histogram of rgb colors in descending order of occurrence
for each histogram, calculate a distance from black (r:0,g:0,b:0) as follows:
for color in image_histogram:
total_distance += color.percentage_of_image * distance(BLACK_RGB, color.rgb)
then sort images by their distances
I was hoping that images of similar color distribution would end up with a similar distance and result in a visual ordering by color. This was not the case, it seems to somewhat work but not like in the image above.
For the distance function, I've tried euclidean distance, hsv sorting (h->s->v) and even Lab distance sorting. None of which has helped
If anyone has a better approach, I would love to know!
I've never done something like this myself, so forgive me if the following approach is naive:
For each image, boil it down to 1 average RGB value by summing the R, G, B values of all pixels, and divide by the total # pixels. Normalize the components to [0..1]
Plot the image in your 2D color space based on the RGB values. This can be a 2D projection of a 3D (r, g, b) vector transformation.
you could convert to HSV and sort by H
Hue is what most people think of when they think "color"
see: RGB to HSV in PHP
Group similar colors using the distance between them and not between them and black, and use the average color in the image.
You might want to check out ImagePlot. I'm not sure if the algorithms behind the system are available, but you can certainly download and run your image collection through the free software to analyze them.
This software is used in many interesting visualizations of massive image collections, millions+
Info: http://lab.softwarestudies.com/p/imageplot.html#whatsnew
Source: https://github.com/culturevis/imageplot