Compare two shapes and identify different points - javascript

I want to add the extra 2 points in the middle from first shape (point 4&6) to the 2nd shape, before and after point 4 of the 2nd shape.
Each shape is an array of [x,y] points following the given order.
How should I start this?

An intermediate point along a line segment PQ is obtained vectorially by a linear combination (1-t) P + t Q. Find the t for the points 4 and 6 on the left and insert the similar points on the right.

Related

Quickly merge many contiguous polygons in javascript

Does anyone know of a way to merge thousands of polygons that are contiguous? I've been using turf's union function to do this in my prototypes but the time it takes grows to be way too slow as the list of polygons increases. I'm hoping/aiming for a solution that takes sub second time.
Here is how I've been doing it.
const turfUnion = require('#turf/union').default;
const polygons = [ ... ];
const result = polygons.merge((m, f) => turfUnion(m, f));
As I mentioned this is too slow. It takes close to 5 minutes to merge 10,000 features.
I'm guessing there is a way to do this much faster given that I know which polygons share a point with which other polygons and that all the polygons are contagious. The final result can have holes so the solution has to focus on interior perimeters as well as well as the external one.
Any ideas or open source solutions would be great. Solutions in Javascript are preferred, but other low level languages would be OK.
And here is a picture of one of large sets of polygons I'm looking to merge. The data for this can be found here.
And here is the expected output.
Pairwise combine the polygons recursively The cost of computing the union of two polygons scales with the number of points in each. So you can reduce the runtime by reducing the number of operations that involve large polygons.
The approach I take is to combine polygon1 with polygon2, then polygon3 with polygon4, all the way up to polygon(N-1) with polygonN.
Then I repeat the process combining polygon1_2 (the union of polygons 1 and 2 from the previous step) with polygon3_4, all the way up to combining polygon(N-3)_(N-2) with polygon(N-1)_(N).
Keep repeating this process until you only have one polygon remaining.
Here's some sample code. It's python, not Javascript, but porting it shouldn't be difficult.
def union(geom_list):
"""Rapidly combine a list of geometries into one.
Inputs
---------
geom_list
A list of gdal/ogr geometries
Returns
-----------
A single geometry representing the union of the inputs
"""
if len(geom_list) == 1:
return geom_list[0]
if len(geom_list) == 2:
return geom_list[0].Union(geom_list[1])
size = int(np.floor(len(geom_list)/2))
geom1 = union(geom_list[:size])
geom2 = union(geom_list[size:])
return geom1.Union(geom2)
I can't claim this is the fastest possible way to do it, but it's much faster than adding one polygon at a time.
At the risk of sending you down a rabbit hole, here's what I would try if I was in your shoes...
Stage 1: O(n). Consolidate all the line segments into an array, such that you end up with an array of line segments (ie, [x0,y0,x1,y1]) representing every polygon...
[
[30.798218847530226, -26.663920391848013, 30.798209281734188, -26.66394228167575],
[30.798209281734188, -26.66394228167575, 30.798201318284743, -26.663914720621534],
[30.798201318284743, -26.663914720621534, 30.798218847530226, -26.663920391848013],
...
]
Stage 2: O(n log n). Sort this entire array by x0, such that the line segments are now ordered according to the x value of the beginning of the segment.
Stage 3: O(1). Beginning with the first element in the sorted array (segment 0), we can make the assumption that the segment with the leftmost x0 value has to be on the edge of the outer polygon. At this point we have segment 0's [x0,y0,x1,y1] as the starting outer edge segment.
Stage 4: O(log n). Now, find the corrresponding line segments that begin with the end of the previous segment. In other words, which segments connect to the current segment? This should be less than a handful, typically one or two. Searching for the matching x0 is assumed to be binary, followed by a short localized linear search for all matching [x0,y0] combinations.
Stage 5: O(1). If only one segment's [x0,y0] matched the last segment's [x1,y1], then add the segment to the list of outer edges. If more than one matching segment was found, then (assuming that we're moving in a clockwise direction) find the [x0,y0] pair that is furthest left of the current line segment, or if the outer edge is taking a right turn and none of the matching segments is to the left, then the [x0,y0] pair that is closest to the right of the current line segment. Add this new segment to the list of outer edges.
(Note that there are matrix algorithms, which avoid the more expensive trig functions, to determine whether a point is to the left or right of a segment, in addition to the perpendicular distance from a point to a line / segment.)
Stage 6: O(~n). Repeat Stage 4 until back at the starting outer edge segment.
Overall algorithm should be O(n log n)...
Note that this does not take into account interior perimeters, but believe that if you can determine a beginning segment that forms part of an interior perimeter and know whether the starting segment is moving clockwise or counterclockwise, then the same algorithm should work...

Question about how to get coordinate point intersect of 2 line in draw i.o

My question is how do get a coordinate point intersect of 2 line in draw i.o
I need a function to resolve this problem in javascript (get coordinate of point only)
Example:
With the start and end points of both of those lines, you can calculate their slopes. Since you have at least one point you can then compute the slope-intercept form of the lines and set the y's equal to each other to calculate the intersection points' Cartesian coordinates.

Geometry on Latitude/Longitude (Projection of point on arc)

I just want to check if there is a point (lat, long) of the projection intersecting with the arc giving by 2 points (lat, long) and if it does, I want to find that (lat, long).
Can (lat, long) be used as a 2D vector space to make this problem similar to the one in cartesian co-ordinates? How accurate would it be?
While the answer on Link helps with getting the distance to the arc, how can I know whether the point of intersection is between the points that were used to find the great circle? Also would it be possible to solve this without having to use switch to cartesian co-ordinates?
There are two ways to approach this.
The first assumes a straight line between the two points--although, in actuality, such a line would intersect with the earth.
The second actually determines the great-circle route between the two points, that is, the minimum-length arc that actually follows the earth's surface and joins the two points. To do this, you have to use coordinate transformations to generate vectors of direction cosines for the two superficial points. Call them A and B.
To determine whether C lies on that arc, you can't just do linear interpolation like you could if you cheated and used a line segment that passes through the earth. Instead, you need to calculate the direction cosines for C also. C lies true between A and B if angles AC, BC, and AB are all equal. Angles can be determined by calculating the dot products of the corresponding direction cosines and evaluating the inverse cosine thereof.

Find where a bisectrix interesects a specific area of an Image

First of all I am using javascript and KineticJS.
I have a picture of an xray(so you can picture what kind of colors its using) and the picture is a profile picture of the scull like these. I have some lines that are formed after users clicks at some specific points, which some of them intersect. In a pair of them I need to know when the bisectrix of the angle formed by the two intersecting lines, intersect with a specific part of the scull that is when the bone starts (which is greyer i think) My question is there a good way of checking this? I mean Suppoze i take each point on my bisectrix line and check the color of the pixels? How can I be sure since xrays might differ(film brightness etc). Could you give me a suggestion or lead me to somewhere?
Your question is a bit confusing.
If 2 lines intersect then 4 angles are created and therefore 4 bisecting lines are created.
Anyway here's how to get started...
Once you determine which points are interesting, you can use context.getImageData to fetch the rgba values of the pixels at those points.
Then convert each rgba pixel color to hsl format. Hsl format separates the Hue, Saturation & Lightness of a color.
Bones & teeth appear lighter so you can compare lightness values to discover bone/teeth.
[ Addition: Calculating points along the bisecting line ]
If you know the intersection point of 2 lines [x,y] and you know the angle you're interested in (radianAngle), then you can compute a point at distance (d) along the line that bisects that angle like this:
var lineX = x + d * Math.cos(radianAngle);
var lineY = y + d * Math.sin(radianAngle);
Then you can use the data from getImageData to fetch the rgba color at point [lineX,lineY]. Then convert to the hsl format and use the Light value to determine if [lineX,lineY] is over the lighter bone.

Calculating adjacent circle segments

I'm trying to develop a component that should look somewhat like this
I'm using RaphaelJS to draw this and that works just fine. I have an array of angles which I use to calculate the paths of the individual segments. I store these paths in a simple array so the inner circle is at segments[0] and so on spiralling outwards.
My problem is that I need each segment to be aware of it's adjacent segments both clockwise, anti-clockwise, inwards and outwards and I'm having difficulty figuring out how to calculate the position of these is my segment array. So for instance, in the case of the above diagram, the red segment at level 2 (where 0 is the inner-most circle) has red, bright green, kaki, light purple and dark purple neighbours.
Perhaps I need a different coordinate system. If each level had the same number and angle distribution of segments it would be a simple case of using modulus's like indexing a circular array but this isn't the case.
Any help would be much appreciated.
Many Thanks,
Anthony
I'd change how you're storing the segments from one sorted array into one sorted array per level.
Finding the neighbours of a given segment (S) is then fairly easy: the left and right neighbours are the previous and next elements of that level's array.
The neighbours in the adjacent levels are found with a couple of binary searches in those arrays: find the segments that coincide with the start and end angles of S, the neighbours are the sequence of segments between those two.

Categories