예제 #1
0
파일: calc.c 프로젝트: zinuzoid/zCalculator
void approx_sqrti(double val,double *realans,double *imagans)
{
	double result;
	result=approx_pow(zabsf(val),0.5);
	if(val>=0)
	{
		*realans=result;
		*imagans=0;
	}
	else
	{
		*realans=0;
		*imagans=result;
	}
}
예제 #2
0
void FlexAirfoil::updateForces()
{
	if(!airfoil) return;
	if (broken) return;
//	if (innan) {LOG("STEP "+TOSTRING(innan)+" "+TOSTRING(nblu));innan++;}
	//evaluate wind direction
	Vector3 wind=-(nodes[nfld].Velocity+nodes[nfrd].Velocity)/2.0;
	//add wash
	int i;
	for (i=0; i<free_wash; i++)
		wind-=(0.5*washpropratio[i]*aeroengines[washpropnum[i]]->getpropwash())*aeroengines[washpropnum[i]]->getAxis();
	float wspeed=wind.length();
	//chord vector, front to back
	Vector3 chordv=((nodes[nbld].RelPosition-nodes[nfld].RelPosition)+(nodes[nbrd].RelPosition-nodes[nfrd].RelPosition))/2.0;
	float chord=chordv.length();
	//span vector, left to right
	Vector3 spanv=((nodes[nfrd].RelPosition-nodes[nfld].RelPosition)+(nodes[nbrd].RelPosition-nodes[nbld].RelPosition))/2.0;
	float span=spanv.length();
	//lift vector
//if (_isnan(spanv.x) || _isnan(spanv.y) || _isnan(spanv.z)) LOG("spanv is NaN "+TOSTRING(nblu));
//if (_isnan(wind.x) || _isnan(wind.y) || _isnan(wind.z)) LOG("wind is NaN "+TOSTRING(nblu));
	Vector3 liftv=spanv.crossProduct(-wind);
//if (_isnan(liftv.x) || _isnan(liftv.y) || _isnan(liftv.z)) LOG("liftv0 is NaN "+TOSTRING(nblu));
//if (_isnan(liftv.x) || _isnan(liftv.y) || _isnan(liftv.z)) LOG("liftv1 is NaN "+TOSTRING(nblu));

	//wing normal
	float s=span*chord;
	Vector3 normv=chordv.crossProduct(spanv);
	normv.normalise();
	//calculate angle of attack
	Vector3 pwind;
	pwind=Plane(Vector3::ZERO, normv, chordv).projectVector(-wind);
	Vector3 dumb;
	Degree daoa;
	chordv.getRotationTo(-pwind).ToAngleAxis(daoa, dumb);
	aoa=daoa.valueDegrees();
	float raoa=daoa.valueRadians();
	if (dumb.dotProduct(spanv)>0) {aoa=-aoa; raoa=-raoa;};

//if (_isnan(aoa)) LOG("aoa is NaN "+TOSTRING(nblu));
	//get airfoil data
	float cz, cx, cm;
	if (isstabilator)
		airfoil->getparams(aoa-deflection, chordratio, 0, &cz, &cx, &cm);
	else
		airfoil->getparams(aoa, chordratio, deflection, &cz, &cx, &cm);
	//compute surface
//if (_isnan(cz)) LOG("cz is NaN "+TOSTRING(nblu));
	//float fs=span*(fabs(thickness*cos(raoa))+fabs(chord*sin(raoa)));
	//float ts=span*(fabs(chord*cos(raoa))+fabs(thickness*sin(raoa)));

	//tropospheric model valid up to 11.000m (33.000ft)
	float altitude=nodes[nfld].AbsPosition.y;
	//float sea_level_temperature=273.15+15.0; //in Kelvin (not used)
	float sea_level_pressure=101325; //in Pa
	//float airtemperature=sea_level_temperature-altitude*0.0065; //in Kelvin (not used)
	float airpressure=sea_level_pressure*approx_pow(1.0-0.0065*altitude/288.15, 5.24947); //in Pa
	float airdensity=airpressure*0.0000120896;//1.225 at sea level

	Vector3 wforce=Vector3::ZERO;
	//drag
	wforce=(cx*0.5*airdensity*wspeed*s)*wind;

//if (_isnan(wforce.x) || _isnan(wforce.y) || _isnan(wforce.z)) LOG("wforce1 is NaN "+TOSTRING(nblu));
	//induced drag
	if (useInducedDrag) 
	{
		Vector3 idf=(cx*cx*0.25*airdensity*wspeed*idArea*idArea/(3.14159*idSpan*idSpan))*wind;
//if (_isnan(idf.length())) LOG("idf is NaN "+TOSTRING(nblu));

		if (idLeft)
		{
			nodes[nblu].Forces+=idf;
			nodes[nbld].Forces+=idf;
		}
		else
		{
			nodes[nbru].Forces+=idf;
			nodes[nbrd].Forces+=idf;
		}
	}

//if (_isnan(wforce.x) || _isnan(wforce.y) || _isnan(wforce.z)) LOG("wforce1a is NaN "+TOSTRING(nblu));
//if (_isnan(cz)) LOG("cz is NaN "+TOSTRING(nblu));
//if (_isnan(wspeed)) LOG("wspeed is NaN "+TOSTRING(nblu));
//if (_isnan(airdensity)) LOG("airdensity is NaN "+TOSTRING(nblu));
//if (_isnan(s)) LOG("s is NaN "+TOSTRING(nblu));
//if (_isnan(liftv.x) || _isnan(liftv.y) || _isnan(liftv.z)) LOG("liftv is NaN "+TOSTRING(nblu));
	//lift
	wforce+=(cz*0.5*airdensity*wspeed*chord)*liftv;


/*if (_isnan(wforce.x) || _isnan(wforce.y) || _isnan(wforce.z)) 
{
	if (innan==0) innan=1;
	LOG("wforce2 is NaN "+TOSTRING(nblu));
}
*/
	//moment
	float moment=-cm*0.5*airdensity*wspeed*wspeed*s;//*chord;
	//apply forces

	Vector3 f1=wforce*(liftcoef * 0.75/4.0f)+normv*(liftcoef *moment/(4.0f*0.25f));
	Vector3 f2=wforce*(liftcoef *0.25/4.0f)-normv*(liftcoef *moment/(4.0f*0.75f));

	//focal at 0.25 chord
	nodes[nfld].Forces+=f1;
	nodes[nflu].Forces+=f1;
	nodes[nfrd].Forces+=f1;
	nodes[nfru].Forces+=f1;
	nodes[nbld].Forces+=f2;
	nodes[nblu].Forces+=f2;
	nodes[nbrd].Forces+=f2;
	nodes[nbru].Forces+=f2;



//	sprintf(debug, "wind %i kts, aoa %i, cz %f, vf %f ", (int)(wspeed*1.9438), (int)aoa, cz, normv.y);

}
예제 #3
0
파일: calc.c 프로젝트: zinuzoid/zCalculator
double approx_sqrt(double val)
{
	return approx_pow(val,0.5);
}