NaturalIntelligence / imglab

To speedup and simplify image labeling/ annotation process with multiple supported formats.
https://solothought.com/imglab/
MIT License
985 stars 609 forks source link

Adding extra points to SVG polygon (svg.js) #67

Open amitguptagwl opened 6 years ago

amitguptagwl commented 6 years ago

Once a polygon is created, user should be able to add extra points later to change the shape of polygon.

Watch for changes, or Bookmark for easy discovery. Fund this project for new features and maintenance. [Showcase] your project with us by raising an issue

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/60464213-adding-extra-points-to-svg-polygon-svg-js?utm_campaign=plugin&utm_content=tracker%2F76641010&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F76641010&utm_medium=issues&utm_source=github).
kuangmichael07 commented 6 years ago

Hi @amitguptagwl as a newcomer I would love to give it a try. May I have some guidance for this isse? Thank you

amitguptagwl commented 6 years ago

Thanks for the initiative @kuangmichael07 . You may go through this technical guide to understand technical part of this application.

This application use svg.js to draw shapes. Here is the link to draw polygon. You may create some jsfiddle to test it and then migrate it to this app. Or I can help you for migration part once your code is ready.

For migration, you may need to refer these 2 files:

For implementation;

Expectation: When the polygon tool is selected, and user clicks on the edge of the polygon then add an extra point.

I'm not sure if svg.js directly support it. If not, then, in my opinion, on mouse-down event

  1. check if polygon tool is selected, 2a. if yes then check if mouse-coordinate is on edge. (It's not difficult to check) 3a. if yes then add a point to existing polygon shape on mouse-coordinate position.

You may have some different approach. Above explanation is just to make it easy.

kuangmichael07 commented 6 years ago

@amitguptagwl Thanks for the explanation. When I was playing with the imglab, I found there is another problem that the polygon point waiting to be added is NOT exactly at mouse-coordinate position. I will try your approach real quick and give a demo soon

amitguptagwl commented 6 years ago

@kuangmichael07 yes they are not real coordinate but relative to the SVG. You can find a method in app.js to find the relative coordinates.

amitguptagwl commented 6 years ago

@kuangmichael07 I hope you're managing this issue well.

kuangmichael07 commented 6 years ago

@amitguptagwl Amit, I am still working on it, I tried to set it up on jsfiddle by using the example code on svg.draw.js: `var poly1 = new SVG('polygon').size('100%', '100%') .polygon().draw();

    poly1.on('drawstart', function(e){
        document.addEventListener('keydown', function(e){
            if(e.keyCode == 13){
                poly1.draw('done');
                poly1.off('drawstart');
            }
        });
    });

    poly1.on('drawstop', function(){
        // remove listener
    });`

But not be able to start plotting the polygon, looks like it does not take the new points by mouse click. I will need more time than expected on this issue, thank you

amitguptagwl commented 6 years ago

no problem. you may also take the help from other communities like stackoverflow etc. You may share your jsfiddle link here as well.

kuangmichael07 commented 6 years ago

Here is the link: https://jsfiddle.net/adtak1m5/319/

There are two testout in the code, first is just to make sure all the step up is correct and the 'polygon' tag is for our application.

Thank you

amitguptagwl commented 6 years ago

Frankly speaking, I couldn't relate this jsfiddle with this problem. I was expecting to copy paste the same code presents on svg.js demo to draw a polygon. And then work on the solution.

kuangmichael07 commented 6 years ago

That's what this code is trying to do, I copied the code from: http://svgjs.com/svg.draw.js/demo/index.html(from the section: Polygon, press Enter to finish the shape). Please take a look from line 11 in my jsfiddle code. Anything before line 11 is just to double check the functionality of svg.js is correctly set up

On Mon, Jul 23, 2018 at 9:56 AM, Amit Gupta notifications@github.com wrote:

Frankly speaking, I couldn't relate this jsfiddle with this problem. I was expecting to copy paste the same code presents on svg.js demo to draw a polygon. And then work on the solution.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/NaturalIntelligence/imglab/issues/67#issuecomment-407066444, or mute the thread https://github.com/notifications/unsubscribe-auth/AJMMWja4SCdV69qgpa_gEanDNfTDQV-Pks5uJdXvgaJpZM4VCOiL .

amitguptagwl commented 6 years ago

I believe you haven't included svg.draw.js in your jsfiddle.

kuangmichael07 commented 6 years ago

I included svg.min.js. I believe svg.draw.js is just an extension of svg.js and should be included as well, right?

amitguptagwl commented 6 years ago

yes. However I've added some snippet to describe what I actually wanted to explain. check my comment on config.js line 66. This is not the complete code but will give you an idea about how to add a point.

Things to add in that snippet.

  1. current condition check if the point is near to previously added points. But we'll have to find if the point is near the edge.
  2. Once the point is added to polyarray, it should be reflected on the canvas.
  3. and so on.
kuangmichael07 commented 6 years ago

Thanks! I got your idea. working on it now. Will let you know once I get it done. https://jsfiddle.net/kuangmichael07/5xsz9wd3/68/

amitguptagwl commented 6 years ago

I've updated the code, now it can add a point to polygon.

We've to still work on how to find if mouse pointer is near to edge. Or we can find the distance of each point and can plot this point between 2 closest points.

amitguptagwl commented 6 years ago

@kuangmichael07 I've added the code to determine the correct point and add to the polygon. Next to do;

Ashape is drawn in 2 ways

I've added the snippet for manual approach. We'll have to extract it in a function and will need to call that function at the time of drawing polygon manually or automatically. (workarea.tag.hteml)

I hope I'm clear.

kuangmichael07 commented 6 years ago

@amitguptagwl I made some change on your updated code and it works like now: https://jsfiddle.net/kuangmichael07/5xsz9wd3/151/ I think the codes in line 70 to 73 should update all the 'i's to 'p_i'shttps://github.com/NaturalIntelligence/imglab/commit/9e1c24e661ac4bc9af097c3a56a5fefe9f6c84e7

It now can add a new point by 'double click' and replot the polygon. But there is a problem that when you want to add a new point between the first and the last points, it won't work.

amitguptagwl commented 6 years ago

I think I had updated 'i' to 'p_i', in next commit (though not completely sure). jsfiddle you mentioned is really good.

I can understand the issue you mentioned. But I believe it can be easily handle. Because we need only 2 points to know the distance which can be anywhere.

kuangmichael07 commented 6 years ago

@amitguptagwl I have made some update again to fix three problems that I can think of:

  1. It can now add new point btw the last and first points in polygon shape
  2. It fixes the issue that new points can be added outside of the polygon by replacing "ploy.on(){}"(line 66) to "myCanvas.on(){}".
  3. Change the algorithm to find the splice index in the polyArray by finding the closet line to the new points instead of comparing the distance by "distance < 11"(line 80)

Here is the new demo: https://jsfiddle.net/kuangmichael07/5xsz9wd3/177/

Please give it a try and let me know how I should further improve it. Thanks Amit

kuangmichael07 commented 6 years ago

Actually I do think that the best way to add new point is by dragging the line that the user wants to add a new point to. This would be more intuitive or we can not precisely decide which line the user wants to add a new point. I can quickly write a demo today to show the difference

amitguptagwl commented 6 years ago

It's really a good demo. I'm not able to imagine how would it look when user will try to drag line. So better I'll wait before any comment.

kuangmichael07 commented 6 years ago

@amitguptagwl I have made this new demo and now you can select the specific edge you want by a double click then add a new point(vertex) by right click : https://jsfiddle.net/kuangmichael07/vjg9zsfk/113/

And this article explains why selecting the right edge is important: https://social.msdn.microsoft.com/Forums/en-US/0fe0cbf1-84dc-4aec-93a9-8d90d9eb8184/adding-removing-points-along-a-polygon?forum=vemapcontroldev

Two things I am now not able to accomplish so far:

  1. I am not able to animate the edge drag & add a new point process
  2. For adding the new point, the coordinate is not correct in the canvas, I searched on stack overflow and got the answer but it is kinda hard implemented yet: https://stackoverflow.com/questions/13435690/html5-drag-and-drop-mouse-position-in-firefox

Please let me know if this sounds useful to the original issue. I might be doing something not really improving the project, lol

amitguptagwl commented 6 years ago

:)

The demo is having some issues and creating the point somewhere I'm not targeting.

I agree with the importance of selecting the edge to create point. But it's confusing. Since the thickness of the edge is just 1-2 pixel user will face difficulty to click on the edge to drag, select edge, or create point. Hence I defined a range of 10 pixels.

Since the user can always drag the point to exact location once it is create, I believe your previous solution is better.

https://jsfiddle.net/kuangmichael07/5xsz9wd3/177/

We can add delete point functionality later to make it more practical.

kuangmichael07 commented 6 years ago

Okay cool, so should I start cleaning up the code and learn code migration now? I used to do pull request but I think it is different for this app, right?

amitguptagwl commented 6 years ago

yes. your code should we added to workarea.tag.html file (this file is becoming big so we may think to refactor it). The code need to be called 2 times. So better if we take it in a function, and pass necessary parameters.

kuangmichael07 commented 6 years ago

@amitguptagwl I have rewrite it in a function syntax: https://jsfiddle.net/kuangmichael07/5xsz9wd3/215/ Not sure if you want it to make it immutable or not. I just write it in a conventional way to return a new polygon. Let me know if it is not what you want, thanks

amitguptagwl commented 6 years ago

As such this application is not be gonna used in any other application as library, I'm not really concerned about that. However bounding into a function is good so we can reuse it.

One problem

As there can be multiple polygons, and you're allowing people to add points when he clicks outside, how will you decide which polygon should be used?

kuangmichael07 commented 6 years ago

good point. In that case should I write another function to pre-select the polygon by mouse that user want to add vertex?

amitguptagwl commented 6 years ago

Hmm! I think yes.

amitguptagwl commented 6 years ago

@kuangmichael07 You were pretty much close. Are you still on this issue?

kuangmichael07 commented 6 years ago

@amitguptagwl yes, sorry about replying late. I have found the way to select a polygon but figuring out how to select it among a bunch of polys, especially when there are overlapped polys. Will give you some update by the end of today

kuangmichael07 commented 6 years ago

@amitguptagwl Hi Amit, the demo now is able to select poly by double click and add a new point by a single click. but the remaining problem is that I am not sure why the mouse click events' x/y location is not exactly where I clicked it. Might need some help on this: https://jsfiddle.net/5xsz9wd3/426/

amitguptagwl commented 6 years ago

I appreciate your effort @kuangmichael07 . Without seeing the code, it looks like that you are not subtracting the position of SVG left, top from current mouse coordinates.

However, I'll still suggest that adding an extra point on the edge would be sufficient. So that it can be dragged to modify the shape. You can check vecteezy editor for an idea