<commit_before>//
// Copyright (c) 2011-2014 <NAME> <<EMAIL>>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import math
import FloatExtension
import FloatSize2D
import FloatPoint2D
import FloatBox2D
import IntTransform2D
import text/StringTokenizer
import structs/ArrayList
import FloatEuclidTransform, FloatTransform3D, FloatPoint3D

// The 2D transform is a 3x3 homogeneous coordinate matrix.
// The element order is:
// A D G
// B E H
// C F I

FloatTransform2D: cover {
	a, b, c, d, e, f, g, h, i: Float
	operator [] (x, y: Int) -> Float {
		result : Float
		match (x) {
			case 0 =>
				match (y) {
					case 0 => result = this a
					case 1 => result = this b
					case 2 => result = this c
					case => OutOfBoundsException new(y, 3) throw()
				}
			case 1 =>
				match (y) {
					case 0 => result = this d
					case 1 => result = this e
					case 2 => result = this f
					case => OutOfBoundsException new(y, 3) throw()
				}
			case 2 =>
				match (y) {
					case 0 => result = this g
					case 1 => result = this h
					case 2 => result = this i
					case => OutOfBoundsException new(y, 3) throw()
				}
			case => OutOfBoundsException new(x, 3) throw()
		}
		result
	}
	determinant ::=	this a * this e * this i + this d * this h * this c	+ this g * this b * this f - this g * this e * this c - this d * this b * this i - this a * this h * this f

	translation ::= FloatSize2D new(this g, this h)
	scaling ::= (this scalingX + this scalingY) / 2.0f
	scalingX ::= (this a * this a + this b * this b) sqrt()
	scalingY ::= (this d * this d + this e * this e) sqrt()
	rotation ::= this b atan2(this a)
	inverse: This { get {
		determinant := this determinant
		This new(
			(this e * this i - this h * this f) / determinant,
			(this h * this c - this b * this i) / determinant,
			(this b * this f - this e * this c) / determinant,
			(this g * this f - this d * this i) / determinant,
			(this a * this i - this g * this c) / determinant,
			(this c * this d - this a * this f) / determinant,
			(this d * this h - this g * this e) / determinant,
			(this g * this b - this a * this h) / determinant,
			(this a * this e - this b * this d) / determinant
		)
	}}
	isProjective ::= this determinant != 0.0f
	isAffine ::= this c == 0.0f && this f == 0.0f && this i == 1.0f
	isSimilarity ::= this == This create(this translation, this scaling, this rotation)
	isEuclidian ::= this == This create(this translation, this rotation)
	isIdentity ::= (this a == 1.0f && this e == 1.0f == && this i == 1.0f) && (this b == 0.0f && this c == 0.0f && this d == 0.0f && this f == 0.0f && this g == 0.0f && this h == 0.0f)
	init: func@ (=a, =b, =c, =d, =e, =f, =g, =h, =i)
	init: func@ ~reduced (a, b, d, e, g, h: Float) { this init(a, b, 0.0f, d, e, 0.0f, g, h, 1.0f) }
	init: func@ ~default { this init(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f) }
	setTranslation: func(translation: FloatSize2D) -> This { this translate(translation - this translation) }
	setScaling: func (scaling: Float) -> This { this scale(scaling / this scaling) }
	setXScaling: func (scaling: Float) -> This { this scale(scaling / this scalingX, 1.0f) }
	setYScaling: func (scaling: Float) -> This { this scale(1.0f, scaling / this scalingY) }
	setRotation: func (rotation: Float) -> This { this rotate(rotation - this rotation) }
	translate: func (xDelta, yDelta: Float) -> This { this createTranslation(xDelta, yDelta) * this }
	translate: func ~float (delta: Float) -> This { this translate(delta, delta) }
	translate: func ~point (delta: FloatPoint2D) -> This { this translate(delta x, delta y) }
	translate: func ~size (delta: FloatSize2D) -> This { this translate(delta width, delta height) }
	scale: func (xFactor, yFactor: Float) -> This { this createScaling(xFactor, yFactor) * this }
	scale: func ~float (factor: Float) -> This { this scale(factor, factor) }
	scale: func ~size (factor: FloatSize2D) -> This { this scale(factor width, factor height) }
	rotate: func (angle: Float) -> This { this createZRotation(angle) * this }
	skewX: func (angle: Float) -> This { this createSkewingX(angle) * this }
	skewY: func (angle: Float) -> This { this createSkewingY(angle) * this }
	reflectX: func -> This { this createReflectionX() * this }
	reflectY: func -> This { this createReflectionY() * this }
	identity: static This { get { This new(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f) } }
	toIntTransform2D: func -> IntTransform2D { IntTransform2D new(this a, this b, this c, this d, this e, this f, this g, this h, this i) }
	create: static func (translation: FloatSize2D, scale, rotation: Float) -> This {
		This new(rotation cos() * scale, rotation sin() * scale, -rotation sin() * scale, rotation cos() * scale, translation width, translation height)<commit_msg>Fixed a mistake...<commit_after>//
// Copyright (c) 2011-2014 <NAME> <<EMAIL>>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import math
import FloatExtension
import FloatSize2D
import FloatPoint2D
import FloatBox2D
import IntTransform2D
import text/StringTokenizer
import structs/ArrayList
import FloatEuclidTransform, FloatTransform3D, FloatPoint3D

// The 2D transform is a 3x3 homogeneous coordinate matrix.
// The element order is:
// A D G
// B E H
// C F I

FloatTransform2D: cover {
	a, b, c, d, e, f, g, h, i: Float
	operator [] (x, y: Int) -> Float {
		result : Float
		match (x) {
			case 0 =>
				match (y) {
					case 0 => result = this a
					case 1 => result = this b
					case 2 => result = this c
					case => OutOfBoundsException new(y, 3) throw()
				}
			case 1 =>
				match (y) {
					case 0 => result = this d
					case 1 => result = this e
					case 2 => result = this f
					case => OutOfBoundsException new(y, 3) throw()
				}
			case 2 =>
				match (y) {
					case 0 => result = this g
					case 1 => result = this h
					case 2 => result = this i
					case => OutOfBoundsException new(y, 3) throw()
				}
			case => OutOfBoundsException new(x, 3) throw()
		}
		result
	}
	determinant ::=	this a * this e * this i + this d * this h * this c	+ this g * this b * this f - this g * this e * this c - this d * this b * this i - this a * this h * this f

	translation ::= FloatSize2D new(this g, this h)
	scaling ::= (this scalingX + this scalingY) / 2.0f
	scalingX ::= (this a * this a + this b * this b) sqrt()
	scalingY ::= (this d * this d + this e * this e) sqrt()
	rotation ::= this b atan2(this a)
	inverse: This { get {
		determinant := this determinant
		This new(
			(this e * this i - this h * this f) / determinant,
			(this h * this c - this b * this i) / determinant,
			(this b * this f - this e * this c) / determinant,
			(this g * this f - this d * this i) / determinant,
			(this a * this i - this g * this c) / determinant,
			(this c * this d - this a * this f) / determinant,
			(this d * this h - this g * this e) / determinant,
			(this g * this b - this a * this h) / determinant,
			(this a * this e - this b * this d) / determinant
		)
	}}
	isProjective ::= this determinant != 0.0f
	isAffine ::= this c == 0.0f && this f == 0.0f && this i == 1.0f
	isSimilarity ::= this == This create(this translation, this scaling, this rotation)
	isEuclidian ::= this == This create(this translation, this rotation)
	isIdentity ::= (this a == 1.0f && this e == 1.0f && this i == 1.0f) && (this b == 0.0f && this c == 0.0f && this d == 0.0f && this f == 0.0f && this g == 0.0f && this h == 0.0f)
	init: func@ (=a, =b, =c, =d, =e, =f, =g, =h, =i)
	init: func@ ~reduced (a, b, d, e, g, h: Float) { this init(a, b, 0.0f, d, e, 0.0f, g, h, 1.0f) }
	init: func@ ~default { this init(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f) }
	setTranslation: func(translation: FloatSize2D) -> This { this translate(translation - this translation) }
	setScaling: func (scaling: Float) -> This { this scale(scaling / this scaling) }
	setXScaling: func (scaling: Float) -> This { this scale(scaling / this scalingX, 1.0f) }
	setYScaling: func (scaling: Float) -> This { this scale(1.0f, scaling / this scalingY) }
	setRotation: func (rotation: Float) -> This { this rotate(rotation - this rotation) }
	translate: func (xDelta, yDelta: Float) -> This { this createTranslation(xDelta, yDelta) * this }
	translate: func ~float (delta: Float) -> This { this translate(delta, delta) }
	translate: func ~point (delta: FloatPoint2D) -> This { this translate(delta x, delta y) }
	translate: func ~size (delta: FloatSize2D) -> This { this translate(delta width, delta height) }
	scale: func (xFactor, yFactor: Float) -> This { this createScaling(xFactor, yFactor) * this }
	scale: func ~float (factor: Float) -> This { this scale(factor, factor) }
	scale: func ~size (factor: FloatSize2D) -> This { this scale(factor width, factor height) }
	rotate: func (angle: Float) -> This { this createZRotation(angle) * this }
	skewX: func (angle: Float) -> This { this createSkewingX(angle) * this }
	skewY: func (angle: Float) -> This { this createSkewingY(angle) * this }
	reflectX: func -> This { this createReflectionX() * this }
	reflectY: func -> This { this createReflectionY() * this }
	identity: static This { get { This new(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f) } }
	toIntTransform2D: func -> IntTransform2D { IntTransform2D new(this a, this b, this c, this d, this e, this f, this g, this h, this i) }
	create: static func (translation: FloatSize2D, scale, rotation: Float) -> This {
		This new(rotation cos() * scale, rotation sin() * scale, -rotation sin() * scale, rotation cos() * scale, translation width, translation height)
{'fraction_non_alphanumeric': 0.1359485650391353, 'fraction_numerical': 0.021058516585911295, 'mean_word_length': 3.164920450135817, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 83, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4604434', 'n_tokens_mistral': 3935, 'n_tokens_neox': 3551, 'n_words': 1453}