I'm using Leaflet and Shiny with circle markers. Trying to figure out how to detect if a circle marker overlaps with one or more markers. I need to set the color of each marker based on whether they overlap or not. Have any of you done something like this before? Thankful for any suggestions :)
You can use an accumulator. Represent the empty space as a n by m matrix of 0s, so each cell of the matrix represents a single point of the lowest granularity (like a pixel). Now mark the position of your marking in the accumulator with a 1. If you take the sum of the matrix at this point is should be 1. Now for all points that would be included in your circle mark with a 1 on the same accumulator. Now check the sum of the accumulator, if it is equal to the number of points in the circle + 1 the circle does not cover the point, but if is only equals the number of points the circle the marker is located within the circle.
Edit: If you want to look for overlaps: instead of just setting points to 1, increment the points by 1 for every object including it. So an over laps would have the value of 2 and a triple overlap would be a 3, etc. You could then find these by searching for local or global maximum or minimums.
Related
I have a set of points inside triangle in barycentric coordinates. I want to remap these to effectively produce the dual graph of the triangle
so that for an interpolated value, both the centre point (1/3,1/3,1/3) through to either of the triangle edges (e.g 1/2,0,1/2) should equal 0.
before an after image of a triangle interpolating between red, green
and blue, with the second triangle exhibiting a dark dual graph 'Y'
shape across it.
I realise that I could solve this by further tessellating the triangle and recalculating the barycentres, but I would prefer to avoid that if I can.
Cheers!
Well of course, walk away for half an hour and you find the answer. For a given barycentric coordinate:
Sort the weights in descending order
Take the highest weight. Put all others in a different list.
Subtract the second highest weight from the highest weight.
Use this value as a multiplier to get the result you desire.
This is more of a mathematical question.
I have a list of 2D coordinates of length N. (Nx2 list)
The coordinates are rounded numbers and form a region. The following is an example:
enter image description here
What I would like is to have a border around these points. Like the following:
enter image description here
One option to do this is to
go through the list, and for each coordinate i
check for the 8 possible neighbours j to see
if this point doesn't overlap with given coordinates k .
if this point doesn't overlap with already found border coordinates
This works well, nut needs N*N*8 calculations. For my N=1000 points: 8 million!
Does anyone know how this could be done more efficient?
Best regards,
Martin
If the size of the grid is constrained and is on the order of N as well, you could do better and get to O(N) by making a 2-D array of ints the size of the grid.
Initialize the grid to zeros.
For each point in the list of points, set the point itself to negative in the grid array and set each neighbor that isn't negative to positive.
When you're done, each point in the 2-D grid array that's positive is the border.
Make a sorted container that enforces uniqueness (in c++ STL, that's a std::set) of coordinates. Go through the points, adding each point's eight neighbors to the set if they aren't already in there. Then go though the points a second time, subtracting them from the set if they are in the set. The points that remain are the border. That's O(N*log(N)). In general that's the best you can do. But see my other answer for a better algorithm if additional criteria exist.
I am currently trying to write a shader in unity that draws a triangular pattern around countries in a risk-styled game if both countries are not owned by the same player (visual aid to see your borders).
Right now, I'm having an issue with making the shader set the countries properly.
It always sets country 0 to the left, and country 1 to the right - country 0 and 1 are set programically.
The line, a border, can be between 0 and 359 degrees.
How I find the countries 0 and 1 is I draw 3 points to the left and right of the midpoint of the line, one .01f, one .1f and one 1f away from the midpoints in each direction, then spin them around the midpoint to the appropriate location.
After that I do an even-odd check to see if the points are inside or outside of each country, and compare the weight results (closest gets 3 points, mid gets 2, furthest gets 1, just in case someone builds a really screwed up country that flanks the other country).
In my test map, a close to equally sliced octagon, the borders showed up correctly (after I reversed the positions of country 0 and 1 in the event the angle was over 90 and less then or equal 180). Worked without a flaw, but in other maps it doesn't work very well.
Everything but the country allocation works well, so I'm curious if anyone knows of a better way to figure out which point is to the left or a spun line, or a better conceptual way to handle this.
That above is basically when I'm doing, red being left right being blue, then I'm just checking 3 different spots then weighing in the lefts and rights found with even/odding it into the appropriate countries (one at +/- .01, the other at +/- .1 and the third 1, in case of even/odd rounding issues with closeness).
I then flip them if I find that country A is to the right, as it is on the left according to the angles I had draw. (my shader renders left first and right second, hence why I do this).
which way is left/right on a line?
From last edit is this not your case. Why not use dot product?
So if the line goes in -x direction the result is negative and if in the +x direction then the result is positive. if the result is zero that means the line goes up or down only or it is juts a point. If you need specific direction instead of left/right then use appropriate a vector instead of x axis.
dot(a,b)=a.x*b.x+a.y*b.y in 2D
dot(a,b)=a.x*b.x+a.y*b.y+a.z*b.z in 3D
Image is relevant for cases where a vector is in unit size in that case the result of dot is perpendicular projection of b into a just like on image
on which side is some point?
I think this is what you need.
As you can see if you handle line (P0,P1) and point P you want to classify as triangle then its polygon winding determines also the side of the line. So for implicit axis directions:
CW(clockwise) polygon winding means right side of the line
CCW(counter-clockwise) polygon winding means left side of the line
How to get winding? ... simply compute normal vector and get its Z coordinate. Its polarity (sign) determines winding (CW/CCW or the other way around depends on the coordinate system).
normal vector is computed as cross product of the two vertices of triangle (P1-P0)x(P-P1)
No need to compute other axises just the z so:
normal.z = ((P1.x-P0.x)*(P.y-P1.y)) - ((P1.y-P0.y)*(P.x-P1.x))
Now just do if (normal.z<0) ... else ... it should never be zero unless you call it for point on the line or the line is a point ... look here at similar question: Determine rotation direction /toward/ variable point on a circle
Given a set of centre points in a 2D-Grid and a common radius, I now want to mark all other points (or rather cells) inside of any of the circles formed by a centre point and the radius.
Finding all points inside one of the circles can be done by finding these points in one quarter and applying symmetry.
However, once some of the points have been marked, I now want to omit marking them again for the sake of efficiency. Therefore, all already "inflated" centre points within relevant distance of the next centre point to be drawn have already marked points which our also enclosed by the next circle. (That is, the magnitude of the vector from our point to each of them is smaller than the diameter).
How can I find the set of points within the next circle which have not been marked before?
The figure below shows an example of what I want to omit. Given three points, I draw a circle around each of them and mark each cell inside the circles with a colour in order blue, red, yellow. As you can see, large parts of the circles are overlapping, therefore some of the cells have been marked with each colour.
For a given row in your grid, with a given Y value, you can write a function to calculate whether there are any points inside a circle on that row, and if so the starting and ending X co-ordinate of the interval where the row crosses the circle. In C++-like psuedo-code:
bool getRowCircleInterval(float fRowY, float fCenterX, float fCenterY, float fRadius, float &fStartX, float &fStartY)
{
if((fRowY < fCenterY - fRadius) || (fRowY > fCenterY + fRadius))
return false; // circle does not intersect this row
float fYDiff = fCenterY - fRadius;
float fIntervalWidth = sqrt((fRadius * fRadius) - (fYDiff * fYDiff));
fStartX = fCenterX - fIntervalWidth;
fEndX = fCenterX + fIntervalWidth;
return true;
}
For each row in the range fCenterY - fRadius to fCenterY + fRadius for the circle you want to draw:
Call this function passing the newest circle to get an interval.
Repeatedly call the function again for each circle you have already drawn passing in the same row Y co-ordinate. If it returns true, intersect the returned interval with the existing interval and chop off that part of the existing interval that intersects. Repeat until either no interval is left or you have processed all the previous circles.
If the final interval remaining after processing all previous circles is non-empty, fill in all grid cells in the interval range for the row.
When converting the floating point X values to integer grid cell indices, you will need to use a consistent fill convention. For example you could divide by the grid cell with then convert to integer, and then fill in all points in the range of start X to end X inclusive. In that case, when you are checking two intervals for an overlap, if the new interval is being clipped by a previous interval, the new interval will be exclusive of the previous interval's endpoints.
I have extracted edge using image processing then I selected pixel coordinate using xclick of extracted edge.Is this correct or there is need of reverse y axis coordinate?(Extracted edge is white on black background)
I want to automatically extracted pixel coordinates of extracted edge not by mouse selection.Is there is any command available in scilab?(I use canny edge detector and morphological filter to extract edge)
Please give me some suggestions
Thanks
1.) Whether to reverse the y coordinte or not, depends on the further processing. Any coordinate system can be used if you need only relative measurements and the true orientation of your features is not important (e.g. reversing top and bottom makes no difference if you simply want to count objects or droplets). Hovewer if you want to indicate your found features by plotting a dot, or a line, or a rectangle (e.g. with plot2d or xrect) or a number (e.g. with xnumb) over the image, then it's necessary to match the two coordinate sytems. I recommend this second option and to plot your result over the original image, since this is the easiest way to check your results.
2.) Automatic coordinate extraction can be made by the find function: it returns those indices of the matrix, where the expression is true.
IM=[0,0,0,1;0,0,0,1;0,1,1,1;1,1,0,0]; //edge image, edge = 1, background = 0
disp(IM,"Edge image");
[row,col]=find(IM==1); //row & column indices where IM = 1 (= edge)
disp([row',col'],"Egde coordinates (row, col)");
If your "Egde image" marks the edges not with 1 (or 255, pure white pixel) but with a relatively high number (bright pixel), then you can modify the logical expression of the find function to detect pixels with a value above a certain threshold:
[row,col]=find(IM>0.8); //if edges > a certain threshold, e.g. 0.8
EDIT: For your specific image:
Try the following code:
imagefile="d:\Attila\PROJECTS\Scilab\Stackoverflow\MORPHOLOGICAL_FILTERING.jpg";
//you have to modify this path!
I=imread(imagefile);
IM=imcrop(I,[170,100,950,370]); //discard the thick white border of the image
scf(0); clf(0);
ShowImage(IM,'cropped image');
threshold=100; //try different values between 0-255 (black - white)
[row,col]=find(IM>threshold);
imheight=size(IM,"r"); //image height
row=imheight-row+1; //reverse y axes coordinates (0 is at top)
plot2d(col,row,style=0); //plot over the image (zoom to see the dots)
scf(1); clf(1); //plot separate graph
plot2d(col,row,style=0);
If you play with the threshold parameter, you will see how the darker or whiter pixels are found.