<commit_before>"use strict";

/***** Polygon *****/

function Polygon (vertices, options)
{
	var options = options || {};

	this.display = options.display || window.display;
	this.vertices = vertices; // vertices must be clockwise
	this.position = Point(0, 0);
	this.rotation = 0;
	// this.tilt = 1;
	// this.zoom = 1;

	this.ymin = null;
	this.ymax = null;
	this.left_edges = new Int16Array(this.display.height);
	this.right_edges = new Int16Array(this.display.height);

	this.left_edge_properties = {};
	this.right_edge_properties = {};
	this.row_property_deltas = {};

	// TODO: heightmap-specific, move to subclass?
	this.xheights = new Int16Array(this.display.width);
	this.xheights_empty = new Int16Array(this.display.width);
	for (var i = 0; i < this.xheights_empty.length; i++) {
		this.xheights_empty[i] = this.display.height;
	}
}


/* Rasterization methods */

// TODO: trace left and right edges in tandem?
Polygon.prototype.traceEdges = function (transform, property_keys)
{
	var v, vtop, vtop_index = 0, vstart, vend;
	var line, tracer;
	var off;
	var p = Point(0, 0);
	var properties, k, pk;
	var edge;

	if (transform == null) {
		return false;
	}

	if (this.vertices_trans == null) {
		this.vertices_trans = [];
	}

	// Find top vertex
	for (v = 0; v < this.vertices.length; v ++) {
		this.vertices_trans[v] = Point.rotate(this.vertices[v], this.rotation);

		// Some experiments with view transforms
		// this.vertices_trans[v].y /= this.tilt; // can be used for 'three-quarter view' style
		// this.vertices_trans[v].x *= this.zoom;
		// this.vertices_trans[v].y *= this.zoom;

		if (vtop == null || this.vertices_trans[v].y < vtop.y) {
			vtop = this.vertices_trans[v];
			vtop_index = v;
		}
	}

	// Trace all edges
	for (v = 0; v < this.vertices.length; v ++) {
		vstart = this.vertices[(v + vtop_index) % this.vertices.length];
		vend = this.vertices[(v + vtop_index + 1) % this.vertices.length];

		// line = new Line(Point.rotate(vstart, this.rotation), Point.rotate(vend, this.rotation));
		// line = new Line(vstart, vend);
		line = new Line(this.vertices_trans[(v + vtop_index) % this.vertices.length], this.vertices_trans[(v + vtop_index + 1) % this.vertices.length]);

		// TODO: allow properties to be set via a provided function, to support different data structures
		// property_keys[k](vstart, vend) -> returns [from, to]
		if (property_keys) {
			properties = {};
			for (k in property_keys) {
				pk = property_keys[k];
				properties[pk] = [vstart[pk], vend[pk]];
			}
		}

		edge = 'right';
		if (line.end.y < line.start.y) {
			edge = 'left';
		}
		else if (line.end.y == line.start.y) {
			edge = 'both';
		}

		tracer = new Line.Tracer(line, properties);
<commit_msg>only initialize array for vertex transformations once<commit_after>"use strict";

/***** Polygon *****/

function Polygon (vertices, options)
{
	var options = options || {};

	this.display = options.display || window.display;
	this.vertices = vertices; // vertices must be clockwise
	this.vertices_trans = new Array(this.vertices.length);
	this.position = Point(0, 0);
	this.rotation = 0;
	// this.tilt = 1;
	// this.zoom = 1;

	this.ymin = null;
	this.ymax = null;
	this.left_edges = new Int16Array(this.display.height);
	this.right_edges = new Int16Array(this.display.height);

	this.left_edge_properties = {};
	this.right_edge_properties = {};
	this.row_property_deltas = {};

	// TODO: heightmap-specific, move to subclass?
	this.xheights = new Int16Array(this.display.width);
	this.xheights_empty = new Int16Array(this.display.width);
	for (var i = 0; i < this.xheights_empty.length; i++) {
		this.xheights_empty[i] = this.display.height;
	}
}


/* Rasterization methods */

// TODO: trace left and right edges in tandem?
Polygon.prototype.traceEdges = function (transform, property_keys)
{
	var v, vtop, vtop_index = 0, vstart, vend;
	var line, tracer;
	var off;
	var p = Point(0, 0);
	var properties, k, pk;
	var edge;

	if (transform == null) {
		return false;
	}

	// Find top vertex
	for (v = 0; v < this.vertices.length; v ++) {
		this.vertices_trans[v] = Point.rotate(this.vertices[v], this.rotation);

		// Some experiments with view transforms
		// this.vertices_trans[v].y /= this.tilt; // can be used for 'three-quarter view' style
		// this.vertices_trans[v].x *= this.zoom;
		// this.vertices_trans[v].y *= this.zoom;

		if (vtop == null || this.vertices_trans[v].y < vtop.y) {
			vtop = this.vertices_trans[v];
			vtop_index = v;
		}
	}

	// Trace all edges
	for (v = 0; v < this.vertices.length; v ++) {
		vstart = this.vertices[(v + vtop_index) % this.vertices.length];
		vend = this.vertices[(v + vtop_index + 1) % this.vertices.length];

		line = new Line(
			this.vertices_trans[(v + vtop_index) % this.vertices.length], 
			this.vertices_trans[(v + vtop_index + 1) % this.vertices.length]);

		// TODO: allow properties to be set via a provided function, to support different data structures
		// property_keys[k](vstart, vend) -> returns [from, to]
		if (property_keys) {
			properties = {};
			for (k in property_keys) {
				pk = property_keys[k];
				properties[pk] = [vstart[pk], vend[pk]];
			}
		}

		edge = 'right';
		if (line.end.y < line.start.y) {
			edge = 'left';
		}
		else if (line.end.y == line.start.y) {
			edge = 'both';
		}

		tracer = new Line.Tracer(line, properties);

{'fraction_non_alphanumeric': 0.15796393688955673, 'fraction_numerical': 0.007888805409466567, 'mean_word_length': 3.524214103653356, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1109764', 'n_tokens_mistral': 2090, 'n_tokens_neox': 1922, 'n_words': 458}