GMLscripts.com

Discuss and collaborate on GML scripts
Invert

You are not logged in.

#1 2021-12-06 12:46:04

maras
Member
Registered: 2021-04-25
Posts: 28
Website

draw_curve (cardinal spline)

A curve that goes through all points

Expand/// draw_curve(points_list, tension, closed)
//
//	points_list	a list of points, ds_list
//	tension	0 to 1, real
//	closed	bool
//
//	each point is an array of 2 values [x, y] and they can be simply added like this:
//		ds_list_add(points_list, [x, y]);
//	
/// GMLscripts.com/license

function draw_curve(points_list, tension, closed) {
	
	var ps = [];
	var points_len = ds_list_size(points_list);
	
	if points_len < 2 return;
	
	if !closed {
		for(var i = 0; i < points_len + 1; i++) {
			if i == 0 ps[array_length(ps)] = points_list[| i];
			if i < points_len ps[array_length(ps)] = points_list[| i];
			else ps[array_length(ps)] = points_list[| points_len-1];
		}
	}
	else {
		for(var i = 0; i < points_len + 1; i++) {
			if i == 0 ps[array_length(ps)] = points_list[| points_len-1];
			if i < points_len ps[array_length(ps)] = points_list[| i];
			else {
				ps[array_length(ps)] = points_list[| 0];
				ps[array_length(ps)] = points_list[| 1];
			}
		}
	}
	
	for(var i = 1; i < array_length(ps) - 2; i++) {
		
	    var p0 = ps[i - 1];
	    var p1 = ps[i];
	    var p2 = ps[i + 1];
	    var p3 = ps[i + 2];
		
		var m1x = (1 - tension) * (p2[0] - p1[0] + ((p1[0] - p0[0]) / 1 - (p2[0] - p0[0]) * 0.5));
		var m2x = (1 - tension) * (p2[0] - p1[0] + ((p3[0] - p2[0]) / 1 - (p3[0] - p1[0]) * 0.5));
		var m1y = (1 - tension) * (p2[1] - p1[1] + ((p1[1] - p0[1]) / 1 - (p2[1] - p0[1]) * 0.5));
		var m2y = (1 - tension) * (p2[1] - p1[1] + ((p3[1] - p2[1]) / 1 - (p3[1] - p1[1]) * 0.5));
		
	    var ax = 2 * p1[0] - 2 * p2[0] + m1x + m2x;
	    var ay = 2 * p1[1] - 2 * p2[1] + m1y + m2y;
	    var bx = -3 * p1[0] + 3 * p2[0] - 2 * m1x - m2x;
	    var by = -3 * p1[1] + 3 * p2[1] - 2 * m1y - m2y;
	    var cx = m1x;
	    var cy = m1y;
	    var dx = p1[0];
	    var dy = p1[1];
		
		var amount = 25; // number of points in each segment, 25 is fine
		var prevx = dx;
		var prevy = dy;

	    for(var j = 1; j <= amount; j++) {
	        var t = j / amount;
	        var px = ax * t * t * t + bx * t * t + cx * t + dx;
	        var py = ay * t * t * t + by * t * t + cy * t + dy;
			
			draw_line(px, py, prevx, prevy);
			
			prevx = px;
			prevy = py;
	    }
	}
}

FMDteuO.gif

Expandif mouse_check_button_pressed(mb_left) ds_list_add(list, [mouse_x, mouse_y]);

Last edited by maras (2021-12-06 12:52:38)


I'm on the official GM discord > maras_cz

Offline

Board footer

Powered by FluxBB