how find beetween which points is the cosest point to mouse in a Curve2D?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By newold

I’m trying to create my own 2D curve editor, and I’m stuck in the next step (see image):

I Know the position of green point (i get it with function curve.get_closest_point(_mouse_pos) from the Curve2D) and I need to know between which points it is (in this case is beetween point 1 and point 2) to add at the current Curve2D at this position (i this case, i need add the green point at index = 1)

Can you help me? Thank you

A couple of days ago I asked this question:

Convert a vector2 position to an array index in Curve2D - Archive - Godot Forum

Is it the same thing that you mean?

estebanmolca | 2020-06-10 12:21

yes is the same. I had not seen your question.

I want get the index in which i need put the closest point return by the curve2D function (curve.getclosestpoint(to_point))

newold | 2020-06-10 12:38

I was about to propose as a feature in github a function that returns the id in the array. But for doubts and ignorance I did not. Now that we are 2 with the same problem it would be worth proposing the feature if there is no other solution for this.

estebanmolca | 2020-06-10 12:45

I have solved the problem myself, I put the solution here in case someone else was looking for it (Although I don’t know if this will be the best way):

curve = a valid Curve2D

  1. Get closest point in curve2D
    var closest = curve.get_closest_point(at_position)
  2. get offset for the closest point
    var offset = curve.get_closest_offset(closest)
  3. call function below to get right index
    var index = get_curve_point_index_from_offset(offset)
func get_curve_point_index_from_offset(curve, offset):
	var curve_point_length = curve.get_point_count()
	if curve_point_length < 2: return curve_point_length
	for i in range(1, curve.get_point_count()):
		var current_point_offset = curve.get_closest_offset(curve.get_point_position(i))
		if current_point_offset > offset: return i
	return curve_point_length

newold | 2020-06-10 15:12

Thanks newold, sometimes it just takes a little motivation …

estebanmolca | 2020-06-10 22:01

1 Like
:bust_in_silhouette: Reply From: estebanmolca

Your code works, but in certain situations the mouse did not detect me at the point. Or I didn’t know how to implement it correctly. But it helped me to understand how the functions of Curve2D work a bit. So put this together, much longer but safe. There are details to be polished but nothing that an if cannot solve :-p, It is necessary to implement the control nodes (in and out). I leave it as an answer in case it serves someone.

extends Node2D
onready var curve = $Path2D.curve
var drag = false
var index = -1
enum Tools { SELECT, MOVE , DELETE, CREATE }
onready var current_tool = Tools.SELECT


	
func _input(event):
	if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.is_pressed():
		drag = true
		if current_tool == Tools.SELECT:
			for p in curve.get_point_count():
				if curve.get_point_position(p).distance_to(get_local_mouse_position()) < 10:
					index = p
					current_tool = Tools.MOVE 	
				update()	

	
	if event is InputEventMouseMotion and drag == true:
		if current_tool == Tools.MOVE and index > -1:
			curve.set_point_position(index, curve.get_point_position(index) + event.relative)
			update()
			
	if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and !event.is_pressed():
		drag=false
		#index = null
		current_tool=Tools.SELECT
		update()
		
	if event is InputEventMouseButton and event.button_index == BUTTON_RIGHT and event.is_pressed():
		current_tool=Tools.CREATE
		curve.add_point(get_global_mouse_position()) 
		update()		
	
	
func _draw():
	if curve.get_point_count() > 0:
		draw_polyline(curve.get_baked_points(), Color.red, 2)
	for i in curve.get_point_count():
		var pos=curve.get_point_position(i)	
		draw_circle(pos, 5, Color.blue)
	if (current_tool == Tools.SELECT or current_tool == Tools.MOVE) and (index > -1 and index < curve.get_point_count()): 		
		draw_circle(curve.get_point_position(index), 7 , Color.aliceblue)		
	print(index)
	

It worked! You are my saviour!

Suleymanov | 2020-06-12 06:58