Converting a the outlines of a free drawn path to a polygon - javascript

I want to segment multiple objects within an image using the fabric.js javascript library.
For this example, I want to segment the surfboard. I then want want to convert the drawn shape to a polygon with the coordinates of the outer regions corresponding to the pixel coordinates of the images.
Drawing an segmentation itself it quite straightforward using fabric.js's build in free drawing brush.
I can then convert the coordinates of the drawn path to a polygon using this piece of code:
canvas.on('path:created', function(el){
var path = el.path.path
var points = []
for (var i = 0; i < path.length; i++){
point = {
x: Math.round(path[i][1]),
y: Math.round(path[i][2])
}
points.push(point)
}
shape = new fabric.Polygon(points, {
stroke: 'red',
opacity: 0.5,
strokeWidth: 1,
description: 'aaa',
fill: 'transparent',
});
canvas.add(shape)
})
The red/black link is how I was drawing using the mouse.
After turning drawing mode off and dragging them away, the 2 created objects (the Path from drawing and the polygon) look as follows.
However, because the brush has a certain width, and because of overlapping Path regions, my method of converting it to a poly is not working well.
So I don't want the current polygon I'm outputting (the red one), but instead the outline of the green section. How can I achieve this?
Working fiddle: https://jsfiddle.net/haw54v9L/3/

the free draw paths are many polylines, you must change the polylines to a ploygon. ClipperLib can do this. but there is an accuracy problem when canvas zoom out or zoom in.

Related

Cesium How to draw Polyline using Path positions

I'm using Cesium.SampledPositionProperty() to draw and interpolate path as given in [Reference1]. I'm achieving to draw a Polyline instead of Path for some reasons. To do that I have added a Polyine object inside the entity, and giving it's positions like:
polyline: {
positions: position._property._values,
width: 10,
material: Cesium.Color.GREEN
}
But not getting success. I want to apply Path's interpolation to the polyline also.
Please check the complete effort on Sandcastle link

Calculate area covered by GeoJSON LineString and specified weight of line

I use the following code to draw a GPS track with Leaflet:
const trackJson: L.GeoJSON = L.geoJSON(trackAsJson, {
style: {
color: '#ff0000',
weight: 30,
opacity: 1
}
});
I'd like now calculate the area that is covered by this track, drawn with the specified weight/width. However, I can't find any way to achieve that. All methods that I could find require to have some form of a shape and not just only a line. So I'm either looking for a way to:
Turn the path and the specified weight into a shape
or
Find a direct method to calculate the area of a path and a weight.
If you just need an approximation, you could render the track / path and count the pixels.
How to calculate the area of a java.awt.geom.Area?

Drawing Starbursts – basil.js

I am trying to draw a starburst by first drawing a polygon and then adjusting its properties.
on indesignjs.de it says a polygon is any shape that is not a rectangle, ellipse, or graphic line. When you add a polygon, InDesign creates a regular polygon based on the current polygon preferences settings. But I can't for the life of me figure out how to draw the damn thing.
I wrote this:
var myPolygon = polygon(0, 0, 10, 10);
property(myPolygon, "numberOfSides", 8);
property(myPolygon, "insetPercentage", 50);
but I get an error in indesign saying that polygon is not a function. Is is truncated like rectangle is (i.e. poly)?
As fabianmoronzirfas pointed out, polygon() is not a basil.js function (as opposed to rect()). So either you would have to draw the shape yourself using basil commands like this:
beginShape();
vertex(23, 45);
vertex(34, 67);
// draw as many vertices as you need
endShape(CLOSED);
or you would have to use proper (non-basil) InDesign scripting commands to shape your polygon. The thing you want to achieve can be done by using the convertShape() method, which can be used on any shape, so you could create a rect first and then use this method on the rect:
// #include ~/Documents/basiljs/basil.js;
function draw() {
var myPoly = rect(50, 50, 200, 200);
myPoly.convertShape(ConvertShapeOptions.CONVERT_TO_POLYGON, 8, 50);
}

D3 Canvas Globe With Text At LongLat

my question today is about D3 and display text on a globe at a long/lat using Canvas. What I've essentially got is a globe built using mbostock's world tour, which has a list of long/lats and rotates the globe to focus on them. I've already got markers at the points, but what I'd like is to display some text next to all of the points. At this point in time, it's just city names, but the intention is to display more information as the globe is more fully fleshed out. I've created a plunk with the code: https://plnkr.co/edit/CzfoF4bkPv93l3Yxwu3N?p=preview
The relevant code in that plunk is:
return function(t) {
projection.rotate(r(t));
c.clearRect(0, 0, width, height);
c.fillStyle = "#ccc", c.beginPath(), path(land), c.fill();
for (var j = 0; j < points.length; j++) {
c.fillStyle = "#000", c.beginPath(), path(points[j]), c.fill();
}
c.strokeStyle = "#000", c.lineWidth = 2, c.beginPath(), path(globe), c.stroke();
};
Basically what I'm asking for is a way to display text slightly to the right of specific long/lat coordinates on a globe using canvas. Any and all help is greatly appreciated. Thank you in advance!
The easiest way would be to add a the text in your tween function after you draw the features:
c.fillText(points[i].location,projection(points[i].coordinates)[0]+10,projection(points[i].coordinates)[1]+2);
With the variable projection, projection([long,lat]) returns [x,y], in other words it gives the forward projection of a given point represented by latitude and longitude, returning a coordinate in map coordinate space (your svg or canvas).
Once you have the projected coordinates, you can manipulate those as needed. In this case I added ten to the x value to push the place name further to the right. See this plunker.

Draw polygons on existing SVG to capture coordinate data

We have a web application that displays a SVG map of an office. The map has small icons that represent users walking around with RF tags. This allows administrators of the system to see what rooms users are in. We are using Snap.SVG to load the office SVG file and manipulate it to display the user icons. The challenge is that the map scales to the size of the browser. Using JavaScript to determine the coordinates is not always accurate because the position of the SVG changes based on the browser size.
Here is an example of the map with the icons:
The icons are placed on the map based on X Y coordinates coming from our database. The values for the X Y coordinates are set for each location and were determined using Adobe Illustrator. Currently, we can only place one icon in a room at a time. Because we only have 1 set coordinates the icons overlap if more than one person is in a room at one time.
The second phase of this project is to allow users to draw on of the map to specify locations. Essentially, the user will set points and create a polygon to represent each location on the map. We would use the coordinates of the polygon along with the total area of the polygon to know where on the map we can place icons. This would allow users to define areas without a developer getting involved.
Here is an example of what we want to achieve .
I have been researching how to do this, but have not found anything outside of using something like the Google Maps API to draws polygons on a map. I did find this article that outlines how to dynamically pull points. We thought about using a grid system that is an overlay on the map and the user defines what grid elements are in what locations. So something like [A1,A2,B1,B2]. I persoanlly like the polygon approach as it is more visually appealing and is easier for a user to adopt.
We need some advice on where to start with this and if something like snap.svg is all we need or if we have to rely on other libraries in conjunction with snap.
Update:
With Ian's advice I found a fiddle that describes what he was talking about.
var S;
var pt;
var svg
var box;
window.onload = function(){
svg = $('#mysvg')[0];
S = Snap(svg);
console.log( S );
pt = pt = svg.createSVGPoint(); // create the point
// add the rectangle
box = S.rect(12,12, 12, 12);
box.attr({ fill : 'red', stroke : 'none' });
S.drag(
function(dx, dy, posX, posY, e){
//onmove
pt.x = posX - S.node.offsetLeft;
pt.y = posY - S.node.offsetTop;
console.log(pt.x + "," + pt.y);
// convert the mouse X and Y
//so that it's relative to the svg element
var transformed = pt.matrixTransform(svg.getCTM().inverse());
box.attr({ x : transformed.x, y : transformed.y });
},
function(){
//onstart
},
function(){
//onend
}
);
}
The Fiddle

Categories