// Rotor with surface mounted magnets parallely magnetized
//console.log("------ start script ------");
// Copyright 2018-2024, Vladimir Kuptsov
include('..\\sDraw.js');

function Rotor()
{
	// Rotor inner radius
	this.Rrinner = motor.rotorInnerRadius;
	// Rotor outer radius
	this.Rrouter = motor.rotorOuterRadius;
	// Number of pole pairs
	this.Npp = motor.rotorNumberPolePairs;
	//Air gap length
	var lag = motor.airGap;
	
	// Default rotor dimensions:
	// Magnet depth:
	this.Dpm = 0.2*(this.Rrouter - this.Rrinner);
	if (this.Npp > 2) {
		// Magnet width:
		this.Wpm = 0.7*2*(this.Rrouter - this.Dpm)*Math.tan(Math.PI/this.Npp/2);
	}else {
		// Magnet width:
		var gamma = Math.PI/4;
		this.Wpm = 0.5*2*(this.Rrouter - this.Dpm)*Math.tan(gamma);
	}
	// Magnet fillet radius
	this.Fpm = 0;
	// Magnet inset depth		
	this.Dis = 0;
	// Magnetization: "Radial" | "Parallel"
	this.Magnetization = "Parallel";
	// Retaining sleeve type: Non-conductive or no retaining sleeve | Conductive retaining sleeve
	this.RetainingSleeveType = "Non-conductive or no retaining sleeve";
	// Retaining sleeve thickness
	this.Trs = 0;
	
	this.wpm_real = null; //реальная ширина основания магнита
	
	this.Trs_real = null;  // actual retaining sleeve thickness
	
	this.R_3_1 = null; //Свойство хранения радиуса дуги воздушного пространства
	
};

/**
* Статический метод определения максимального радиуса скругления между двумя кругами с одним центром
*/
Rotor.prototype.getMaxRadiusFilletByRadiuses = function(type){
	switch(type){
	case 'inner':
		//>>>return (Math.pow(this.Rrouter, 2) - Math.pow((this.Rrouter - this.Dpm), 2))/(2 * (this.Rrouter - this.wpm_real / 2 ));
		return (Math.pow(this.Rrouter - this.Trs_real, 2) - Math.pow((this.Rrouter - this.Trs_real - this.Dpm), 2))/(2 * (this.Rrouter - this.Trs_real - this.wpm_real / 2 ));
	case 'outer':
		return (Math.pow(this.Rrinner + this.Dpm, 2) - Math.pow(this.Rrinner, 2))/(2 * (this.Rrinner + this.wpm_real / 2 ));
	}
}

Rotor.prototype.bildFilletIntersection = function (){
	var g1 = couplingSegments(this.line_5_2, this.arc_2_1, this.fpm_tmp); 
	
	this.geomr.push(g1[0]);
	this.geomr.push(g1[1]);
	this.geomr.push(g1[2]);
	
	this.arc_fpm = g1[2];
	this.p_line_5_2 = g1[0];
	this.point_2_r = new QPointF(this.p_line_5_2.p1.x(), this.p_line_5_2.p1.y()); //точка 2 находится на вершине линии 5-2
}

Rotor.prototype.calcAngle_0_9 = function (type){
	switch(type){
	case 'inner':
		//>>>return 90 - Math.radToDeg(Math.asin((this.wpm_real / 2 - this.fpm_tmp)/(this.Rrouter - this.fpm_tmp)));
		return 90 - Math.radToDeg(Math.asin((this.wpm_real / 2 - this.fpm_tmp)/(this.Rrouter - this.Trs_real - this.fpm_tmp)));
	case 'outer':
		return 90 - Math.radToDeg(Math.asin((this.wpm_real / 2 - this.fpm_tmp)/(this.Rrinner + this.fpm_tmp)));
	}
}

Rotor.prototype.calcRealDis = function (){
	this.dis_r = this.Dis;
	this.full_sinking = false;
	this.point_5x = null; //точка на линии 5-2, определяющая начало дуги ограничивающей сталь
	if(this.p_line_5_2 == null || this.dis_r < 0.001 || (Math.abs(this.alfa_pm - this.alfa) < 0.001)){
		//Радиус скругления максимальный и соответственно линии 5-2 нет либо погружение = 0, либо угол основания магнита равен alfa (180 el deg)
		this.dis_r = 0;
		this.point_5x = new QPointF(this.point_5.x(), this.point_5.y());
	}else if(this.p_line_5_2 !== null){
		var len_line_5_2 = this.p_line_5_2.length;
		if(len_line_5_2 <= this.dis_r){
			if(this.fpm_tmp > 0.001){
				console.warn('Insert depth was reduced not to overlap the magnet fillet.');
				this.point_5x = new QPointF(this.p_line_5_2.p1.x(), this.p_line_5_2.p1.y());
				//this.dis_r = null;
			}else{
				this.full_sinking = true;
				this.point_5x = new QPointF(this.point_2.x(), this.point_2.y());
				//this.dis_r = this.Dpm;
			}
		}
	}
}

Rotor.prototype.resetGeometry = function (){
	if(this.t<10){
		this.t = this.t + 1;
		return this.calcGeometry(); //???	
	}
	return;
}

// generate rotor geometry 
// call from с++ code
Rotor.prototype.getGeometry = function (){
	this.wpm_real = this.Wpm;
	this.dpm_real = this.Dpm;
	if (this.RetainingSleeveType == "Conductive retaining sleeve") {
		this.Trs_real = this.Trs; }
	else {
		this.Trs_real = 0; }
	this.t = 0;
	return this.calcGeometry();
}


Rotor.prototype.calcGeometry = function (){
	// Machine type: InnerRotor | OuterRotor
	var machineType = motor.machineType;
	// Rotor inner radius
	this.Rrinner = motor.rotorInnerRadius;
	// Rotor outer radius
	this.Rrouter = motor.rotorOuterRadius; 
	// Number of pole pairs
	this.Npp = motor.rotorNumberPolePairs;
	// Air gap length
	this.lag = motor.airGap;
	
	// draw rotor geometry
	this.geomr = new Array;
	
	var point_0 = new QPointF(0, 0);
	
	this.alfa = 360/this.Npp/4; //угол 1-0-6
	
	//this.alfa_pm = this.alfa*(this.apm_real/180);  //угол 1_0_5
	
	var line_0_3 = sDraw.createLineByPointAngle(0, 0, 90-this.alfa);
	
	var circle_Rrouter = sDraw.createCircle(0, 0, this.Rrouter);
	var circle_Rrinner = sDraw.createCircle(0, 0, this.Rrinner);
	
	if (motor.isInnerRotor()) {  // inner rotor
		if(this.Rrouter - this.dpm_real - this.Trs_real < this.Rrinner){
			this.Trs_real = this.Rrouter - this.Rrinner - this.dpm_real;
			if (this.Trs_real < 0) {
				this.Trs_real = 0; }
			if (this.RetainingSleeveType == "Conductive retaining sleeve" && this.Trs > 0) {
				console.warn('The retaining sleeve thickness has been corrected to fit the available space: Trs = ' + this.Trs_real); }
		}
		if(this.Rrouter - this.dpm_real < this.Rrinner){
			this.dpm_real = this.Rrouter - this.Rrinner;
			console.warn('Magnet depth is greater than the difference between the outer and inner radius. Magnet depth has been corrected: Dpm = ' + this.dpm_real);
		}
		var circle_Rsleeve = sDraw.createCircle(0, 0, this.Rrouter - this.Trs_real);   // sleeve inner radius circle
		
		var point_1 = new QPointF(0, this.Rrouter - this.Trs_real);
		
		//Находим угол основания магнита
		//>>>this.alfa_pm = Math.radToDeg(Math.asin(this.wpm_real / 2 / (this.Rrouter - this.dpm_real)));
		this.alfa_pm = Math.radToDeg(Math.asin(this.wpm_real / 2 / (this.Rrouter - this.Trs_real - this.dpm_real)));
		
		//>>>var circle_Rpm = sDraw.createCircle(0, 0, this.Rrouter - this.dpm_real);
		var circle_Rpm = sDraw.createCircle(0, 0, this.Rrouter - this.Trs_real - this.dpm_real);
		var point_6 = sDraw.intersection(line_0_3, circle_Rpm, 'right');
		if(isNaN(this.alfa_pm) || this.alfa_pm - this.alfa > 0.00001){
			//т5 = т6
			this.point_5 = new QPointF(point_6.x(), point_6.y());
			this.alfa_pm = this.alfa;
			//>>>this.wpm_real = 2 * (this.Rrouter - this.dpm_real) * Math.sin(Math.degToRad(this.alfa_pm));// коррекция
			this.wpm_real = 2 * (this.Rrouter - this.Trs_real - this.dpm_real) * Math.sin(Math.degToRad(this.alfa_pm));// коррекция
			console.warn('Magnet width exceeds the sector limits. Magnet width has been corrected: Wpm = ' + this.wpm_real);
			return this.resetGeometry();
		}
			
		var line_0_5 = sDraw.createLineByPointAngle(0, 0, 90-this.alfa_pm);
		this.point_5 = sDraw.intersection(line_0_5, circle_Rpm, (this.alfa_pm == 90) ? 'right' : 'higher'); 
		//Находим угол верхушки магнита
		//>>>this.alfa_pm_1_0_2 = Math.radToDeg(Math.asin((this.wpm_real / 2) / this.Rrouter));
		this.alfa_pm_1_0_2 = Math.radToDeg(Math.asin((this.wpm_real / 2) / (this.Rrouter - this.Trs_real)));
		
		var line_0_2 = sDraw.createLineByPointAngle(0, 0, 90-this.alfa_pm_1_0_2);
		
		//>>>this.point_2 = sDraw.intersection(line_0_2, circle_Rrouter, (this.alfa_pm_1_0_2 == 90) ? 'right' : 'higher');
		this.point_2 = sDraw.intersection(line_0_2, circle_Rsleeve, (this.alfa_pm_1_0_2 == 90) ? 'right' : 'higher');

		//>>>var arc_3_1 = new Arc(Math.radToDeg(line_0_3.angleRad), 90, this.Rrouter, 0, 0);
		var arc_3_1 = new Arc(Math.radToDeg(line_0_3.angleRad), 90, this.Rrouter - this.Trs_real, 0, 0);
		//>>>var arc_5_4 = new Arc(Math.radToDeg(line_0_5.angleRad), 90, this.Rrouter - this.dpm_real, 0, 0);
		var arc_5_4 = new Arc(Math.radToDeg(line_0_5.angleRad), 90, this.Rrouter - this.Trs_real - this.dpm_real, 0, 0);
		var arc_8_7 = new Arc(Math.radToDeg(line_0_3.angleRad), 90, this.Rrinner, 0, 0);
		this.line_5_2 = new Segment(this.point_5, this.point_2);
		var s_line_5_2 = sDraw.createLineBy2Points(this.point_5.x(), this.point_5.y(), this.point_2.x(), this.point_2.y());
		//>>>this.arc_2_1 = new Arc(Math.radToDeg(line_0_2.angleRad), 90, this.Rrouter, 0, 0);
		this.arc_2_1 = new Arc(Math.radToDeg(line_0_2.angleRad), 90, this.Rrouter - this.Trs_real, 0, 0);
		
		this.geomr.push(arc_5_4);    // arc 5-4
		this.geomr.push(arc_8_7);    // arc 8-7
		
		this.point_2_r = null; //реальное положение точки 2
		
		//Максимальный радиус скругления
		var fpm_max = this.getMaxRadiusFilletByRadiuses('inner');
		var fpm_max_y = this.wpm_real / 2;
		var angle_0_9_real;
		if(this.Fpm >= fpm_max){
			console.warn('Magnet fillet radius does not fit magnet size; maximum possible fillet radius is used instead');
			//Проверка на пересечение с осью y - проверяем на условие (this.wpm_real / 2) <= this.fpm_tmp
			this.fpm_tmp = fpm_max;
			var angle_0_9 = this.calcAngle_0_9('inner');
			if((this.wpm_real / 2) <= this.fpm_tmp){
				console.warn('Magnet fillet radius intersects the y axis. Magnet fillet radius has been corrected');
				//Скругляем пересечение
				this.fpm_tmp = fpm_max_y;
				this.bildFilletIntersection();
				angle_0_9_real = 90;
			}else{
				//Строим дугу с максимальным радиусом скругления
				//точка 9 - находим 
				var line_0_9 = sDraw.createLineByPointAngle(point_0.x(), point_0.y(), angle_0_9);
				//>>>var point_9 = sDraw.intersection(line_0_9, circle_Rrouter, 'higher');
				var point_9 = sDraw.intersection(line_0_9, circle_Rsleeve, 'higher');
				var arc1 = sDraw.createArcBy2PointsAndRadius(point_9.x(), point_9.y(), this.point_5.x(), this.point_5.y(), this.fpm_tmp, 1);
				//>>>var arc_1_9 = new Arc(Math.radToDeg(line_0_9.angleRad), 90, this.Rrouter, 0, 0);
				var arc_1_9 = new Arc(Math.radToDeg(line_0_9.angleRad), 90, this.Rrouter - this.Trs_real, 0, 0);
				
				this.geomr.push(arc_1_9);
				this.geomr.push(arc1);
				
				this.arc_fpm = arc1;
				this.p_line_5_2 = null;
				this.point_2_r = new QPointF(this.point_5.x(), this.point_5.y()); //точка 2 = точке 5
				angle_0_9_real = angle_0_9;
			}
		}else{
			//Проверка на пересечение с осью y - проверяем на условие (this.wpm_real / 2) <= this.fpm_tmp
			this.fpm_tmp = this.Fpm;
			var angle_0_9 = this.calcAngle_0_9('inner');
			if((this.wpm_real / 2) <= this.fpm_tmp){
				console.warn('Magnet fillet radius intersects the y axis. Magnet fillet radius has been corrected');
				//Скругляем пересечение
				this.fpm_tmp = fpm_max_y;
				this.bildFilletIntersection();
				angle_0_9_real = 90;
			}else{
				//Скругляем пересечение
				this.bildFilletIntersection();
				angle_0_9_real = angle_0_9;
			}
		}
			
		//Вычисляем погруженность магнита в сталь, т.е. радиус дуги 6-5
		this.calcRealDis();
		if(this.point_5x !== null){
			//Находим радиус дуги стали
			this.Rosteel = calcLengthBy2Points(0, 0, this.point_5x.x(), this.point_5x.y());
		}else if(this.point_5x == null){
			//Находим точку на линии 5-2
			var angle_0_5_2 = 90 + Math.radToDeg(line_0_5.angleRad);
			this.point_5x = new QPointF(this.point_5.x(), this.point_5.y() + this.dis_r);
			//Узнаем радиус дуги стали
			this.Rosteel = calcLengthBy2Points(0, 0, this.point_5x.x(), this.point_5x.y());
		}
		//Вычисляем угол начала дуги
		//Зная точку 5х находим угол линии 0-5х
		var line_0_6x = sDraw.createLineBy2Points(0, 0, this.point_5x.x(), this.point_5x.y());
		var arc_6_5 = new Arc(Math.radToDeg(line_0_3.angleRad), Math.radToDeg(line_0_6x.angleRad), this.Rosteel, 0, 0);
		
		this.geomr.push(arc_6_5);    // arc 6-5
		
		//Строим дугу 3-1
		if(this.fpm_tmp > 0.001 && this.Trs_real == 0){
			var circe_fpm = sDraw.createCircle(this.arc_fpm.centerX, this.arc_fpm.centerY, this.arc_fpm.radius);  // magnet fillet full circle
			// determine the aiggap mesh border notch in magnet fillet area (to prevent sharp angle between rotor-airgap border and fillet)
			var notchdepth = this.lag/5;      // notch depth is 20% of air gap length
			if (notchdepth > this.arc_fpm.radius/2) {
				notchdepth = this.arc_fpm.radius/2; }
			var circle_Rnotchdepth = sDraw.createCircle(0, 0, this.Rrouter - notchdepth);  
			var point_notch1 = sDraw.intersection(circle_Rnotchdepth, circe_fpm, 'right');  // notch first point (where notch crossing magnet fillet)
			//console.info("point_notch1: " + point_notch1);
			var line_notch = sDraw.createLineByPointAngle(point_notch1.x(), point_notch1.y(), 45);   // notch angle is 45 degrees
			var point_notch2 = sDraw.intersection(line_notch, circle_Rrouter, 'higher');   // notch second point (where notch crossing rotor-airgap border)
			var line_0_point_notch2 = sDraw.createLineBy2Points(0, 0, point_notch2.x(), point_notch2.y());
			// create rotor-airgap border with notch
			if (Math.radToDeg(line_0_point_notch2.angleRad) > 90 - this.alfa) {					
				var arc_3_point_notch2 = new Arc(90 - this.alfa, Math.radToDeg(line_0_point_notch2.angleRad), this.Rrouter, 0, 0);
				this.geomr.push(arc_3_point_notch2);
			}else{
				point_notch2 = sDraw.intersection(line_0_3, circle_Rrouter, 'higher');   // change notch second point
			}
			var segment_notch = new Segment(point_notch1, point_notch2);
			this.geomr.push(segment_notch);
			this.R_3_1 = this.Rrouter;
		}else if(this.fpm_tmp > 0.001 && this.Trs_real > 0){
			var circe_fpm = sDraw.createCircle(this.arc_fpm.centerX, this.arc_fpm.centerY, this.arc_fpm.radius);  // magnet fillet full circle
			// determine the aiggap mesh border notch in magnet fillet area (to prevent sharp angle between rotor-airgap border and fillet)
			var notchdepth = this.Trs_real/10;      // notch depth is 10% of retaining sleeve thickness
			if (notchdepth > this.arc_fpm.radius/2) {
				notchdepth = this.arc_fpm.radius/2; }
			var circle_Rnotchdepth = sDraw.createCircle(0, 0, this.Rrouter - this.Trs_real - notchdepth);  
			var point_notch1 = sDraw.intersection(circle_Rnotchdepth, circe_fpm, 'right');  // notch first point (where notch crossing magnet fillet)
			//console.info("point_notch1: " + point_notch1);
			var line_notch = sDraw.createLineByPointAngle(point_notch1.x(), point_notch1.y(), 45);   // notch angle is 45 degrees
			var circle_sleeve_innerborder = sDraw.createCircle(0, 0, this.Rrouter - this.Trs_real);
			var point_notch2 = sDraw.intersection(line_notch, circle_sleeve_innerborder, 'higher');   // notch second point (where notch crossing inner retaining sleeve border)
			//console.info("point_notch2: " + point_notch2);
			var line_0_point_notch2 = sDraw.createLineBy2Points(0, 0, point_notch2.x(), point_notch2.y());
			// create rotor-retaining sleeve border with notch
			if (Math.radToDeg(line_0_point_notch2.angleRad) > 90 - this.alfa) {
				var arc_3_point_notch2 = new Arc(90 - this.alfa, Math.radToDeg(line_0_point_notch2.angleRad), this.Rrouter - this.Trs_real, 0, 0);
				this.geomr.push(arc_3_point_notch2);
			}else{
				point_notch2 = sDraw.intersection(line_0_3, circle_sleeve_innerborder, 'higher');   // change notch second point
			}
			var segment_notch = new Segment(point_notch1, point_notch2);
			this.geomr.push(segment_notch);
			//this.R_3_1 = this.Rrouter;
			//this.geomr.push(arc_3_1);    // arc 3-1
			this.R_3_1 = this.Rrouter - this.Trs_real;
		}else{
			this.geomr.push(arc_3_1);    // arc 3-1
			this.R_3_1 = this.Rrouter - this.Trs_real;
		}	
		
		var beta = this.alfa_pm + (this.alfa-this.alfa_pm)/2;
		this.line_general = sDraw.createLineByPointAngle(0, 0, 90-beta+0.01);
		var circle_Rpm_general = sDraw.createCircle(0, 0, (this.R_3_1 + this.Rosteel)/2);
		this.circle_Rpm_iron = sDraw.createCircle(0, 0, (this.Rrinner + this.Rosteel)/2);
		
		if (this.Trs_real>0) {
			var arc_3rs_1rs = new Arc(Math.radToDeg(line_0_3.angleRad), 90, this.Rrouter, 0, 0);
			this.geomr.push(arc_3rs_1rs);    // arc 3rs-1rs of retaining sleeve
		}
	}
	else {      // outer rotor	
		//console.log('444s');
		if(this.Rrouter - this.dpm_real < this.Rrinner){
			this.dpm_real = this.Rrouter - this.Rrinner;
			console.warn('Magnet depth is greater than the difference between the outer and inner radius. Magnet depth has been corrected: Dpm = ' + this.dpm_real);
		}
		
		var point_1 = new QPointF(0, this.Rrinner);
		
		//Находим угол основания (низа) магнита
		this.alfa_pm = Math.radToDeg(Math.asin(this.wpm_real / 2 / (this.Rrinner)));
		
		var point_3 = sDraw.intersection(line_0_3, circle_Rrinner, 'right');
		if(isNaN(this.alfa_pm) || this.alfa_pm - this.alfa > 0.00001){
			//т2 = т3
			this.alfa_pm = this.alfa;
			this.wpm_real = 2 * (this.Rrinner) * Math.sin(Math.degToRad(this.alfa_pm));// коррекция
			console.warn('Magnet width exceeds the sector limits. Magnet width has been corrected: Wpm = ' + this.wpm_real);
			return this.resetGeometry();
		}
		//console.log('ghgh');
		var circle_Rpm = sDraw.createCircle(0, 0, this.Rrinner + this.dpm_real);
		var point_6 = sDraw.intersection(line_0_3, circle_Rpm, 'right');
		
		//Находим ширину основания магнита
		//this.Wpm = 2 * (this.Rrinner + this.Dpm) * Math.sin(Math.degToRad(this.alfa_pm));
		//if((this.Wpm/2 - this.Rrinner) < 0.0000001 && (this.Wpm/2 - this.Rrinner) > 0){
		//	this.Wpm = this.Rrinner * 2;
		//}
		this.alfa_pm_1_0_5 = Math.radToDeg(Math.asin((this.wpm_real / 2) / (this.Rrinner + this.dpm_real)));
		//if(isNaN(this.alfa_pm_1_0_5) || this.alfa_pm_1_0_2 - this.alfa > 0.001){
			//Потенциальная вершина магнита вышла за правую границу сектора - коррекция и новый расчет
		//	this.alfa_pm_1_0_2 = this.alfa;
		//	this.alfa_pm = Math.radToDeg(Math.asin((this.Rrinner / (this.Rrinner + this.Dpm)) * Math.sin(Math.degToRad(this.alfa_pm_1_0_2))));
		//	this.apm_real = this.alfa_pm * 180 / this.alfa;
		//	console.warn('Apm corrected. Apm = '+this.apm_real);
		//	return this.calcGeometry(); //???
		//}
		var line_0_5 = sDraw.createLineByPointAngle(0, 0, 90-this.alfa_pm_1_0_5);
		var line_0_2 = sDraw.createLineByPointAngle(0, 0, 90-this.alfa_pm);
		//console.log('hfgh');
		if(Math.abs(this.alfa_pm - this.alfa) < 0.001){
			//Временная коррекция сдвига точки 2 пока не исправлена функция couplingSegments
			this.point_2 = new QPointF(point_3.x() - 0.0001, point_3.y());
		}else{
			this.point_2 = sDraw.intersection(line_0_2, circle_Rrinner, 'higher'); 
		}		
		this.point_5 = sDraw.intersection(line_0_5, circle_Rpm, (this.alfa_pm == 90) ? 'right' : 'higher'); 
		
		var arc_3_1 = new Arc(Math.radToDeg(line_0_3.angleRad), 90, this.Rrinner, 0, 0);
		var arc_5_4 = new Arc(Math.radToDeg(line_0_5.angleRad), 90, this.Rrinner + this.dpm_real, 0, 0);
		var arc_8_7 = new Arc(Math.radToDeg(line_0_3.angleRad), 90, this.Rrouter, 0, 0);
		this.line_5_2 = new Segment(this.point_5, this.point_2);
		var s_line_2_5 = sDraw.createLineBy2Points(this.point_2.x(), this.point_2.y(), this.point_5.x(), this.point_5.y());
		this.arc_2_1 = new Arc(Math.radToDeg(line_0_2.angleRad), 90, this.Rrinner, 0, 0);
			
		this.geomr.push(arc_5_4);    // arc 5-4
		this.geomr.push(arc_8_7);    // arc 8-7
		//Максимальный радиус скругления
		var fpm_max = this.getMaxRadiusFilletByRadiuses('outer');
		var fpm_max_y = this.wpm_real / 2;
		var angle_0_9_real;
		if(this.Fpm >= fpm_max){
			console.warn('Magnet fillet radius does not fit magnet size; maximum possible fillet radius is used instead');
			//Проверка на пересечение с осью y - проверяем на условие (this.wpm_real / 2) <= this.fpm_tmp
			this.fpm_tmp = fpm_max;
			var angle_0_9 = this.calcAngle_0_9('outer');
			if((this.wpm_real / 2) <= this.fpm_tmp){
				console.warn('Magnet fillet radius intersects the y axis. Magnet fillet radius has been corrected');
				//Строим дугу с максимальным радиусом скругления
				//точка 9 = точка 1
				//Скругляем пересечение
				this.fpm_tmp = fpm_max_y;
				this.bildFilletIntersection();
				angle_0_9_real = 90;
			}else{
				//точка 9 - находим 
				var line_0_9 = sDraw.createLineByPointAngle(point_0.x(), point_0.y(), angle_0_9);
				var point_9 = sDraw.intersection(line_0_9, circle_Rrinner, 'higher');
				var arc1 = sDraw.createArcBy2PointsAndRadius(this.point_5.x(), this.point_5.y(), point_9.x(), point_9.y(), this.fpm_tmp, 1);
				var arc_1_9 = new Arc(Math.radToDeg(line_0_9.angleRad), 90, this.Rrinner, 0, 0);
				this.geomr.push(arc_1_9);
				this.geomr.push(arc1);
				this.arc_fpm = arc1;
				this.p_line_5_2 = null;
				this.point_2_r = new QPointF(this.point_5.x(), this.point_5.y()); //точка 2 = точке 5
				angle_0_9_real = angle_0_9;
			}
		}else{
			//Проверка на пересечение с осью y - проверяем на условие (this.wpm_real / 2) <= this.fpm_tmp
			this.fpm_tmp = this.Fpm;
			var angle_0_9 = this.calcAngle_0_9('outer');
			if((this.wpm_real / 2) <= this.fpm_tmp){
				console.warn('Magnet fillet radius intersects the y axis. Magnet fillet radius has been corrected');
				//Скругляем пересечение
				this.fpm_tmp = fpm_max_y;
				this.bildFilletIntersection();
				angle_0_9_real = 90;
			}else{
				this.bildFilletIntersection();
				angle_0_9_real = angle_0_9;
			}
		}
		//console.dir(this.arc_fpm);
				
		//Вычисляем погруженность магнита в сталь, т.е. радиус дуги 6-5
		this.calcRealDis();
		if(this.point_5x !== null){
			//Находим радиус дуги стали
			this.Risteel = calcLengthBy2Points(0, 0, this.point_5x.x(), this.point_5x.y());
		}else if(this.point_5x == null){
			//Находим точку на линии 5-2
			var angle_0_5_2 = 90 + Math.radToDeg(line_0_5.angleRad);
			this.point_5x = new QPointF(this.point_5.x(), this.point_5.y() - this.dis_r);
			//Узнаем радиус дуги стали
			//this.Rosteel = Math.sqrt(Math.pow(this.dis_r, 2) + Math.pow((this.Rrouter - this.Dpm), 2) - 2 * this.dis_r * (this.Rrouter - this.Dpm) * Math.cos(Math.degToRad(angle_0_5_2)));
			this.Risteel = calcLengthBy2Points(0, 0, this.point_5x.x(), this.point_5x.y());
			
			//Знаем радиус дуги стали, вычислим точку 5х
			//this.Risteel = this.Rrinner + this.Dpm - this.dis_r;
			//Находим точку на линии 5-2
			//var angle_0_5_2 = 90 - Math.radToDeg(line_0_5.angleRad);
			//var length_5_5x = this.Risteel / Math.sin(Math.degToRad(angle_0_5_2)) * Math.sin(Math.degToRad(180 - angle_0_5_2 - Math.radToDeg(Math.asin((this.Rrinner + this.Dpm) * Math.sin(Math.degToRad(angle_0_5_2)) / this.Risteel))));
			//var length_5_5x = (this.Rrinner + this.Dpm) * Math.cos(Math.degToRad(angle_0_5_2)) - Math.sqrt(Math.pow(this.Risteel, 2) - Math.pow(((this.Rrinner + this.Dpm) * Math.sin(Math.degToRad(angle_0_5_2))), 2));
			//this.point_5x = new QPointF(this.point_5.x(), this.point_5.y() - length_5_5x);
		}
		//Вычисляем угол начала дуги
		//Зная точку 5х находим угол линии 0-5х
		var line_0_6x = sDraw.createLineBy2Points(0, 0, this.point_5x.x(), this.point_5x.y());
		var arc_6_5 = new Arc(Math.radToDeg(line_0_3.angleRad), Math.radToDeg(line_0_6x.angleRad), this.Risteel, 0, 0);
		this.geomr.push(arc_6_5);    // arc 6-5
		
		//Строим дугу 3-1
		if(this.fpm_tmp > 0.001){
			var circe_fpm = sDraw.createCircle(this.arc_fpm.centerX, this.arc_fpm.centerY, this.arc_fpm.radius);  // magnet fillet full circle
			// determine the aiggap mesh border notch in magnet fillet area (to prevent sharp angle between rotor-airgap border and fillet)
			var notchdepth = this.lag/5;     // notch depth is 20% of air gap length
			if (notchdepth > this.arc_fpm.radius/2) {
				notchdepth = this.arc_fpm.radius/2; }
			var circle_Rnotchdepth = sDraw.createCircle(0, 0, this.Rrinner + notchdepth);
			var point_notch1 = sDraw.intersection(circle_Rnotchdepth, circe_fpm, 'right');  // notch first point (where notch crossing magnet fillet)
			var line_notch = sDraw.createLineByPointAngle(point_notch1.x(), point_notch1.y(), -45);   // notch angle is -45 degrees
			var point_notch2 = sDraw.intersection(line_notch, circle_Rrinner, 'higher');   // notch second point (where notch crossing rotor-airgap border)																	 
			var line_0_point_notch2 = sDraw.createLineBy2Points(0, 0, point_notch2.x(), point_notch2.y());
			// create rotor-airgap border with notch
			if (Math.radToDeg(line_0_point_notch2.angleRad) > 90 - this.alfa) {
				var arc_3_point_notch2 = new Arc(90 - this.alfa, Math.radToDeg(line_0_point_notch2.angleRad), this.Rrinner, 0, 0);
				this.geomr.push(arc_3_point_notch2);
			}else{
				point_notch2 = sDraw.intersection(line_0_3, circle_Rrinner, 'higher');   // change notch second point
			}
			var segment_notch = new Segment(point_notch1, point_notch2);
			this.geomr.push(segment_notch);
			//this.geomr.push(new Arc(90 - this.alfa, 90 - this.alfa+10, this.Rrinner+3, 0, 0));
		}else{
			//var arc_3_2 = new Arc(90 - alfa, 90 - alfa_pm, this.Rrinner, 0, 0);
			this.geomr.push(arc_3_1);    // arc 3-1
		}		
		this.R_3_1 = this.Rrinner;
			
		var beta = this.alfa_pm + (this.alfa-this.alfa_pm)/2;
		this.line_general = sDraw.createLineByPointAngle(0, 0, 90-beta+0.01);
		var circle_Rpm_general = sDraw.createCircle(0, 0, (this.Risteel + this.R_3_1) / 2);
		this.circle_Rpm_iron = sDraw.createCircle(0, 0, (this.Rrinner + this.dpm_real + this.Risteel)/2);
	}
	
	this.point_general = sDraw.intersection(this.line_general, circle_Rpm_general, 'higher');   // point to assign general material
	
	this.t = 0;
	
	return this.geomr;
};

// call from с++ code
Rotor.prototype.getMaterials = function() { // assign material types

	var materials = new Array();
	var delta = 0.001;
	
	if (Math.abs(motor.rotorOuterRadius - motor.rotorInnerRadius - this.Trs_real) > this.dpm_real) {
		if (motor.isInnerRotor()) {  // inner rotor
			materials.push( new IronMaterial(delta, (motor.rotorOuterRadius - this.dpm_real - this.Trs_real + motor.rotorInnerRadius) / 2)); }   // rotor iron
		else {   // outer rotor		
			materials.push( new IronMaterial(delta, (motor.rotorOuterRadius + motor.rotorInnerRadius + this.dpm_real) / 2)); }   // rotor iron
	}else if(Math.abs(motor.rotorOuterRadius - motor.rotorInnerRadius - this.Trs_real) == this.dpm_real && this.dis_r > 0 && Math.abs(this.alfa_pm - this.alfa) > 0.001){
		//console.dir(this.circle_Rpm_iron);
		this.point_iron = sDraw.intersection(this.line_general, this.circle_Rpm_iron, 'higher');  // point to assign iron material
		//console.log(this.point_iron);
		if (motor.isInnerRotor()) {  // inner rotor
			materials.push( new IronMaterial(this.point_iron.x(), this.point_iron.y())); }   // rotor iron
		else {   // outer rotor		
			materials.push( new IronMaterial(this.point_iron.x(), this.point_iron.y())); }   // rotor iron
	}
	
	if (this.alfa_pm > 0 && this.dpm_real > 0) {   // magnet
		if (this.Magnetization == "Radial") {
			var materialMagnet = new MagnetRadialMaterial; }
		else if (this.Magnetization == "Parallel") {
			var materialMagnet = new MagnetParallelMaterial; }
		else { 
			console.error('Undefined magnetization type'); }
		materialMagnet.center = new QPointF(0, 0);
		materialMagnet.direction = Direction.From;
		materialMagnet.angle = 90;  
		if (motor.isInnerRotor()) {  // inner rotor
			materialMagnet.pos = new QPointF(delta, motor.rotorOuterRadius - this.Trs_real - this.dpm_real/2);
		}
		else {   // outer rotor		
			materialMagnet.pos = new QPointF(delta, motor.rotorInnerRadius + this.dpm_real/2);
		}
		materials.push(materialMagnet); 
	}
	
	// general
	if (this.dpm_real > 0 && !this.full_sinking) {
		materials.push( new GeneralMaterial(this.point_general.x(), this.point_general.y())); 
	} 
	
	if (this.Trs_real > 0) { // retaining sleeve (conductor)
		materials.push( new ConductorMaterial(delta, motor.rotorOuterRadius - this.Trs_real/2)); }
	
	return materials;
};
	
var rotor = new Rotor();

// rotor widgets constuctor
function RotorUI(ui)
{
	this.ui = ui;

	this.labelDpm = new QLabel("Magnet depth (Dpm):");
	this.labelDpm.toolTip = "Use the ‘? Guide’ button above for explanation on this parameter";
	this.editDpm = new QDoubleSpinBox;
	this.editDpm.objectName = "Dpm";
	this.editDpm.setRange(0.0, motor.rotorOuterRadius);
	this.editDpm.decimals = 2;
	this.editDpm.singleStep = 1;
	this.editDpm.keyboardTracking = false;
	this.editDpm.value = rotor.Dpm;
	//this.editDpm['valueChanged(double)'].connect(this, function(value){
	//	rotor.Dpm = value;
	//});
	this.unitsDpm = new QLabel("mm");
	
	this.labelWpm = new QLabel("Magnet width (Wpm):");
	this.labelWpm.toolTip = "Use the ‘? Guide’ button above for explanation on this parameter";
	this.editWpm = new QDoubleSpinBox;
	this.editWpm.objectName = "Wpm";
	this.editWpm.setRange(0.0, (motor.rotorOuterRadius * 2));
	this.editWpm.decimals = 2;
	this.editWpm.singleStep = 1;
	this.editWpm.keyboardTracking = false;
	this.editWpm.value = rotor.Wpm;
	//this.editWpm['valueChanged(double)'].connect(this, function(value){
	//	rotor.Wpm = value;
	//});
	this.unitsWpm = new QLabel("mm");
	
	this.labelFpm = new QLabel("Magnet fillet radius (Fpm):");
	this.labelFpm.toolTip = "Use the ‘? Guide’ button above for explanation on this parameter";
	this.editFpm = new QDoubleSpinBox;
	this.editFpm.objectName = "Fpm";
	this.editFpm.setRange(0.0, Math.abs(motor.rotorOuterRadius));
	this.editFpm.decimals = 2;
	this.editFpm.singleStep = 0.1;
	this.editFpm.keyboardTracking = false;
	this.editFpm.value = rotor.Fpm;
	//this.editFpm['valueChanged(double)'].connect(this, function(value){
	//	rotor.Fpm = value;
	//});
	this.unitsFpm = new QLabel("mm");
	
	this.labelDis = new QLabel("Magnet inset depth (Dis):");
	this.labelDis.toolTip = "Use the ‘? Guide’ button above for explanation on this parameter";
	this.editDis = new QDoubleSpinBox;
	this.editDis.objectName = "Dis";
	this.editDis.setRange(0.0, Math.abs(motor.rotorOuterRadius));
	this.editDis.decimals = 2;
	this.editDis.singleStep = 1;
	this.editDis.keyboardTracking = false;
	this.editDis.value = rotor.Dis;
	//this.editDis['valueChanged(double)'].connect(this, function(value){
	//	rotor.Dis = value;
	//});
	this.unitsDis = new QLabel("mm");
	
	this.labelRetainingSleeveType = new QLabel("Retaining sleeve:");
	this.labelRetainingSleeveType.toolTip = "Use 'Conductive retaining sleeve' item to include eddy current loss in retaining sleeve into analysis." + "\n" +
	"Retaining sleeve will use material assigned for 'Conductor' in the 'Materials' panel on the right." + "\n" +
	"Retaining sleeve loss will appear in the 'Other eddy current loss' parameter of 'Magnetostatic Analysis'";
	this.comboboxRetainingSleeveType = new QComboBox();
	this.comboboxRetainingSleeveType.objectName = "RetainingSleeveType";
	this.comboboxRetainingSleeveType.addItem("Non-conductive or no retaining sleeve");
	this.comboboxRetainingSleeveType.addItem("Conductive retaining sleeve");
	this.comboboxRetainingSleeveType.currentText = rotor.RetainingSleeveType;
	this.comboboxRetainingSleeveType.toolTip = "Use 'Conductive retaining sleeve' item to include eddy current loss in retaining sleeve into analysis." + "\n" +
	"Retaining sleeve will use material assigned for 'Conductor' in the 'Materials' panel on the right." + "\n" +
	"Retaining sleeve loss will appear in the 'Other eddy current loss' parameter of 'Magnetostatic Analysis'";
	//this.comboboxRetainingSleeveType['currentIndexChanged(int)'].connect(this, function(value){
	//	rotor.RetainingSleeveType = this.comboboxRetainingSleeveType.currentText;
	//});
	
	this.labelMagnetization = new QLabel("Magnetization:");
	this.comboboxMagnetization = new QComboBox();
	this.comboboxMagnetization.objectName = "Magnetization";
	this.comboboxMagnetization.addItem("Radial");
	this.comboboxMagnetization.addItem("Parallel");
	this.comboboxMagnetization.currentText = rotor.Magnetization;
	//this.comboboxMagnetization['currentIndexChanged(int)'].connect(this, function(value){
	//	rotor.Magnetization = this.comboboxMagnetization.currentText;
	//});
	
	this.labelTrs = new QLabel("Retaining sleeve thickness (Trs):");
	this.labelTrs.toolTip = "Use the ‘? Guide’ button above for explanation on this parameter";
	this.editTrs = new QDoubleSpinBox;
	this.editTrs.objectName = "Trs";
	this.editTrs.setRange(0, Math.abs(motor.rotorOuterRadius - motor.rotorInnerRadius));
	this.editTrs.decimals = 1;
	this.editTrs.singleStep = 1;
	this.editTrs.keyboardTracking = false;
	this.editTrs.value = rotor.Trs;
	//this.editTrs['valueChanged(double)'].connect(this, function(value){
	//	rotor.Trs = value;
	//});
	this.unitsTrs = new QLabel("mm");
	
	this.layout = new QGridLayout(ui);
	
	this.layout.addWidget(this.labelDpm, 0, 0);
	this.layout.addWidget(this.editDpm, 0, 1);
	this.layout.addWidget(this.unitsDpm, 0, 2);

	this.layout.addWidget(this.labelWpm, 1, 0);
	this.layout.addWidget(this.editWpm, 1, 1);
	this.layout.addWidget(this.unitsWpm, 1, 2);
	
	this.layout.addWidget(this.labelFpm, 2, 0);
	this.layout.addWidget(this.editFpm, 2, 1);
	this.layout.addWidget(this.unitsFpm, 2, 2);
			
	this.layout.addWidget(this.labelDis, 3, 0);
	this.layout.addWidget(this.editDis, 3, 1);
	this.layout.addWidget(this.unitsDis, 3, 2);
	
	this.layout.addWidget(this.labelMagnetization, 4, 0);
	this.layout.addWidget(this.comboboxMagnetization, 4, 1, 1, 2);
	
	this.layout.addWidget(this.labelRetainingSleeveType, 5, 0);
	this.layout.addWidget(this.comboboxRetainingSleeveType, 5, 1, 1, 2);
	
	this.layout.addWidget(this.labelTrs, 6, 0);
	this.layout.addWidget(this.editTrs, 6, 1);
	this.layout.addWidget(this.unitsTrs, 6, 2);
};

// update rotor widgets
RotorUI.prototype.updateUI = function()
{
	//console.log("rotorUI.updateUI");
	
	if (motor.isInnerRotor()) {  // inner rotor
		var visibleRetainingSleeveType = true;
		var visibleTrs = rotor.RetainingSleeveType == "Conductive retaining sleeve";
	}
	else {                       // outer rotor
		var visibleRetainingSleeveType = false;
		var visibleTrs = false;
	}
	this.labelRetainingSleeveType.setVisible(visibleRetainingSleeveType);
	this.comboboxRetainingSleeveType.setVisible(visibleRetainingSleeveType);
	this.labelTrs.setVisible(visibleTrs);
	this.editTrs.setVisible(visibleTrs);
	this.unitsTrs.setVisible(visibleTrs);
}

// call this function from c++ code
createRotorUI = function(ui)
{
	rotorUI = new RotorUI(ui);
	rotorUI.updateUI();
}

	

	
	
	
