How to draw triangle wave using ZedGraph? - c#

How to draw triangle wave (symmetrical) using ZedGraph?
alt text http://img101.imageshack.us/img101/8482/okr20troj.jpg
Preferably with option to adjust period and amplitude.
//Edit: the function has to be [related/based on]? x (x-axis).
Something like this:
for (x = 0; x <= 10; x += .005)
{
if (Math.Sin(x * (2 * Math.PI / period)) >= 0)
y = amplitude;
else
y = -amplitude;
originalList.Add(x, y);
}

double amplitude = 1.7;
double period = 2;
PointPairList ppl = new PointPairList();
double y=0;
for (double x = 0; x <= 10; x += .005)
{
double p = (x % (period)) / period ;
if (p >= 0 && p <= 0.25)
y = 4 * p * amplitude;
if (p > 0.25 && p < 0.5)
y = amplitude - (p - 0.25) * 4 * amplitude;
if(p>0.5 && p<=0.75)
y = - 4 * (p-0.5) * amplitude;
if(p>0.75 && p<=1)
y = - (amplitude - (p - 0.75) * 4 * amplitude);
ppl.Add(x,y);
}
var line = zg1.MasterPane[0].AddCurve("", ppl, Color.Blue);
line.Symbol.IsVisible = false;
zg1.AxisChange();
zg1.Refresh();

Related

Selecting an enemy from a non sorted weighted list

I have been itching my head as to why this is not working like it should. I have a list that changes probability of monster spawning every second. i want to select a random weighted enemy from this list. Somewhere im going wrong and i think it is around the "EnemyToSpawnNext = Enemies[sorted[T].Key].Enemie[0].EnemyPrefab;" area.
public GameObject EnemySelection()
{
var sorted = TierProbability.Select((x, i) => new KeyValuePair<int, float>(i, x)).OrderBy(x => x.Value).ToList();
List<int> idx = sorted.Select(x => x.Key).ToList();
List<float> B = sorted.Select(x => x.Value).ToList();
float P = UnityEngine.Random.Range(0, 1);
float Sum_prob = 0;
for (int T = 0; T < TotalNumberofTiers; T++)
{
Sum_prob += sorted[T].Value;
print(Sum_prob);
if (Sum_prob >= P)
{
EnemyToSpawnNext = Enemies[sorted[T].Key].Enemie[0].EnemyPrefab;
break;
}
}
return EnemyToSpawnNext;
}
the following is the difficulty adjustment function that created the list of probabilitys.
public void DifficultyAdjustments()
{
SecondsElapsed += 10; // for debugging
Min_Tier += 10 * (End_Min_Tier - Start_Min_Tier) / (TimeinMinutes * 60);
Peak_Tier += 10 * (End_Peak_Tier - Start_Peak_Tier) / (TimeinMinutes * 60);
Max_tier += 10 * (End_Max_Tier - Start_Max_Tier) / (TimeinMinutes * 60);
for (int T = 0; T < TotalNumberofTiers; T++)
{
if (T < Min_Tier)
WeightT = 0;
if (T > Max_tier)
WeightT = 0;
if (Min_Tier <= T & T < Peak_Tier)
WeightT = 1 + (Max_weight - 1) / (Peak_Tier - Min_Tier) * (T - Min_Tier);
if (Peak_Tier <= T & T < Max_tier)
WeightT = 1 + (Max_weight - 1) / (Peak_Tier - Max_tier) * (T - Max_tier);
TierWeights[T] = WeightT;
TierProbability[T] = WeightT / TierWeights.Sum();
}
print(EnemySelection()); // for debugging
}
The problem is your P
float P = UnityEngine.Random.Range(0, 1);
this P always become zero
Use this instead:
float P = UnityEngine.Random.Range(0f, 1f);

How to return two list with a double method? [duplicate]

This question already has answers here:
Return multiple values to a method caller
(28 answers)
Closed 3 years ago.
I'm working on a C# program that getting some values from textboxes and set them to some variables in 2 class that their name is:"Tfluid" and "Twell"
then I use them in another class the name is "Tcalc" through a method with name "fluidcal" and make some calculations with them,
I have 2 crossed while that means it starts with a "ql" and then match a final P to each "ql". now I want to use these (ql, P) to plot a graph in another form,
so what is the best way of saving them
(i don't know what should I return with the fluidal method)
and how can I add them to the chart?
this is my calculation process
public double Fluidcal(TWell well, TFluid fluid)
{
double froudnumber, noslipholdup, vm, vsl, vsg, liquidvelocitynumber, l1, l2, l3, l4, fluidregim, hozhold, C, psy, liqhold, liqholdseg, liqholdinter, fn, nren, densityn, viscosityn, y, S, ftp, dpdzel, dpdzf, dpperdzt, rhos, Ek,ql;
ql = 1;
while (ql<=fluid.maxoilflowrate)
{
vsl = (ql) / Math.PI * Math.Pow(well.tubingdiameter / 2, 2); //superficial velocities
vsg = (ql * fluid.gor) / Math.PI * Math.Pow(well.tubingdiameter / 2, 2);
vm = vsl + vsg;
double nowlength = 0;
double P = well.wellheadpressure;
while (nowlength <= well.welldepth)
{
froudnumber = Math.Pow(vm, 2) / well.tubingdiameter * 32.174; //froud number
noslipholdup = vsl / vm; //no slip holdup
double newoildensity = fluid.oildensity / (1 + 0.00056 * (0.01515 * nowlength));
liquidvelocitynumber = vsl * Math.Pow((newoildensity / 32.174 * fluid.gasliquidsurfacetension), 0.25); //liquid velocity number
//correlating parametrs
l1 = 316 * Math.Pow(noslipholdup, 0.302);
l2 = 0.0009252 * Math.Pow(noslipholdup, -2.4684);
l3 = 0.1 * Math.Pow(noslipholdup, -1.4516);
l4 = 0.5 * Math.Pow(noslipholdup, -6.738);
fluidregim = 0;
C = 0;
liqhold = 0;
if ((noslipholdup < 0.01 && froudnumber < l1) || (noslipholdup >= 0.01 && froudnumber < l2))
{
segregated(froudnumber, noslipholdup, liquidvelocitynumber, out fluidregim, out hozhold, out C, out psy, out liqhold);
}
else if ((noslipholdup >= 0.01 && l2 < froudnumber && froudnumber <= l3))
{
transition(froudnumber, noslipholdup, liquidvelocitynumber, l2, l3, out fluidregim, out hozhold, out C, out psy, out liqhold, out liqholdseg, out liqholdinter);
}
else if ((noslipholdup >= 0.01 && noslipholdup < 0.4 && froudnumber > l3 && froudnumber <= l1)
|| (noslipholdup >= 0.4 && l3 < froudnumber && froudnumber <= 4))
{
intermittent(froudnumber, noslipholdup, liquidvelocitynumber, out fluidregim, out hozhold, out C, out psy, out liqhold);
}
else if ((noslipholdup < 0.4 && froudnumber >= l1) || (noslipholdup >= 0.4 && froudnumber > l4))
{
disturbuted(froudnumber, noslipholdup, out fluidregim, out hozhold, out C, out psy, out liqhold);
}
// else
// {
// System.Windows.Forms.MessageBox.Show("Undefined Flow Regim");
//}
y = noslipholdup / Math.Pow(liqhold, 2);
if (y > 1 && y < 1.2)
{
S = Math.Log(2.2 * y - 1.2);
}
else
{
S = (Math.Log(y)) / (-0.0523 + 3.182 * Math.Log(y) - 0.8725 * Math.Pow(Math.Log(y), 2) + 0.01853 * Math.Pow(Math.Log(y), 4));
}
viscosityn = fluid.oilviscosity * noslipholdup + fluid.gasviscosity * (1 - noslipholdup);
densityn = fluid.oildensity * noslipholdup + (1 - noslipholdup) * fluid.gasdensity;
nren = densityn * vm * (well.tubingdiameter) / viscosityn;
fn = 1 / Math.Pow((2 * Math.Log(nren / (4.5223 * Math.Log(nren) - 3.8215))), 2);
ftp = fn * Math.Exp(S);
rhos = fluid.oildensity * liqhold + fluid.gasdensity * (1 - liqhold);
Ek = rhos * vm * vsg / 32.2 * P;
dpdzel = (1) * rhos;
dpdzf = ftp * densityn * Math.Pow(vm, 2) / 2 * 32.174 * well.tubingdiameter;
dpperdzt = (dpdzel + dpdzf) / 1 - Ek;
P = P + 5 * dpperdzt;
yax.Add(P);
nowlength = +5;
vsl = vm * liqhold;
vsg = vsl * fluid.gor;
}
ql = +20;
}return; //what should I write here?I want pairs of(ql,P)
There are a few ways you could do this. I would suggest encapsulating the lists in an object and returning that object from your method. For example:
public class MyLists
{
public List<double> ListOne { get; set; }
public List<double> ListTwo { get; set; }
}
Of course, you could use a Tuple. If I understand your question correctly...

C# solution to find the closest point on a latitude/longitude polyline

I am in need of a C# solution to some code i have in Javascript, which takes a array of latitude and longitude positions which forms an area or zone. and also an object X and Y position and returns the X and Y of the closest point from the object. This code works perfect in Javascript, however as i am now re-writing my work in C#, i am unable to find a workable solution which works, and does what this function does.
The Javascript function is below, which takes 2 arguments pXy, which is the X and Y position of your location and aXys, which is an array of X and Y positions forming the polylines of an area.
var getClosestPointOnLines = function(pXy, aXys) {
var minDist;
var fTo;
var fFrom;
var x;
var y;
var i;
var dist;
if (aXys.length > 1) {
for (var n = 1 ; n < aXys.length ; n++) {
if (aXys[n].x != aXys[n - 1].x) {
var a = (aXys[n].y - aXys[n - 1].y) / (aXys[n].x - aXys[n - 1].x);
var b = aXys[n].y - a * aXys[n].x;
dist = Math.abs(a * pXy.x + b - pXy.y) / Math.sqrt(a * a + 1);
}
else
dist = Math.abs(pXy.x - aXys[n].x)
// length^2 of line segment
var rl2 = Math.pow(aXys[n].y - aXys[n - 1].y, 2) + Math.pow(aXys[n].x - aXys[n - 1].x, 2);
// distance^2 of pt to end line segment
var ln2 = Math.pow(aXys[n].y - pXy.y, 2) + Math.pow(aXys[n].x - pXy.x, 2);
// distance^2 of pt to begin line segment
var lnm12 = Math.pow(aXys[n - 1].y - pXy.y, 2) + Math.pow(aXys[n - 1].x - pXy.x, 2);
// minimum distance^2 of pt to infinite line
var dist2 = Math.pow(dist, 2);
// calculated length^2 of line segment
var calcrl2 = ln2 - dist2 + lnm12 - dist2;
// redefine minimum distance to line segment (not infinite line) if necessary
if (calcrl2 > rl2)
dist = Math.sqrt(Math.min(ln2, lnm12));
if ((minDist == null) || (minDist > dist)) {
if (calcrl2 > rl2) {
if (lnm12 < ln2) {
fTo = 0;//nearer to previous point
fFrom = 1;
}
else {
fFrom = 0;//nearer to current point
fTo = 1;
}
}
else {
// perpendicular from point intersects line segment
fTo = ((Math.sqrt(lnm12 - dist2)) / Math.sqrt(rl2));
fFrom = ((Math.sqrt(ln2 - dist2)) / Math.sqrt(rl2));
}
minDist = dist;
i = n;
}
}
var dx = aXys[i - 1].x - aXys[i].x;
var dy = aXys[i - 1].y - aXys[i].y;
x = aXys[i - 1].x - (dx * fTo);
y = aXys[i - 1].y - (dy * fTo);
}
return { 'x': x, 'y': y, 'i': i, 'fTo': fTo, 'fFrom': fFrom };
}
How can i replicate the above in C#?
Thanks xdtTransform. I was not using Visual Studio so did not realize the Ctrl+Space. After installing it, i have managed to convert the code myself. I have included it here for anyone who will benefit from it in the future.
I started with a class to hold the Latitude and Longitude details of the points.
namespace Classes
{
public class AppGeoPoint
{
public double X { get; set; }
public double Y { get; set; }
}
}
And the function converted
public static Classes.AppGeoPoint getClosestPointOnLines(Classes.AppGeoPoint pXy, Classes.AppGeoPoint[] aXys)
{
double? minDist = null;
double fTo = 0.0;
double fFrom;
double x = 0.0;
double y = 0.0;
int i = 0;
double dist;
if (aXys.Length > 1)
{
for (var n = 1; n < aXys.Length; n++)
{
if (aXys[n].X != aXys[n - 1].X)
{
var a = (aXys[n].Y - aXys[n - 1].Y) / (aXys[n].X - aXys[n - 1].X);
var b = aXys[n].Y - a * aXys[n].X;
dist = Math.Abs(a * pXy.X + b - pXy.Y) / Math.Sqrt(a * a + 1);
}
else
dist = Math.Abs(pXy.X - aXys[n].X);
// length^2 of line segment
double rl2 = Math.Pow(aXys[n].Y - aXys[n - 1].Y, 2) + Math.Pow(aXys[n].X - aXys[n - 1].X, 2);
// distance^2 of pt to end line segment
double ln2 = Math.Pow(aXys[n].Y - pXy.Y, 2) + Math.Pow(aXys[n].X - pXy.X, 2);
// distance^2 of pt to begin line segment
double lnm12 = Math.Pow(aXys[n - 1].Y - pXy.Y, 2) + Math.Pow(aXys[n - 1].X - pXy.X, 2);
// minimum distance^2 of pt to infinite line
double dist2 = Math.Pow(dist, 2);
// calculated length^2 of line segment
double calcrl2 = ln2 - dist2 + lnm12 - dist2;
// redefine minimum distance to line segment (not infinite line) if necessary
if (calcrl2 > rl2)
dist = Math.Sqrt(Math.Min(ln2, lnm12));
if ((minDist == null) || (minDist > dist))
{
if (calcrl2 > rl2)
{
if (lnm12 < ln2)
{
fTo = 0;//nearer to previous point
fFrom = 1;
}
else
{
fFrom = 0;//nearer to current point
fTo = 1;
}
}
else
{
// perpendicular from point intersects line segment
fTo = ((Math.Sqrt(lnm12 - dist2)) / Math.Sqrt(rl2));
fFrom = ((Math.Sqrt(ln2 - dist2)) / Math.Sqrt(rl2));
}
minDist = dist;
i = n;
}
}
var dx = aXys[i - 1].X - aXys[i].X;
var dy = aXys[i - 1].Y - aXys[i].Y;
x = aXys[i - 1].X - (dx * fTo);
y = aXys[i - 1].Y - (dy * fTo);
}
return new Classes.AppGeoPoint { X = x, Y = y };
}
Then finally, to build an array list and check for the closest point
Classes.AppGeoPoint YourLocation= new Classes.AppGeoPoint { X = 50.83737, Y = -1.07428 };
Classes.AppGeoPoint[] AreaCheck = new[] {
new Classes.AppGeoPoint { X = 50.847550000000005, Y = -1.0863200000000002 },
new Classes.AppGeoPoint { X = 50.83975, Y = -1.0859800000000002 },
new Classes.AppGeoPoint { X = 50.83845, Y = -1.06487 },
new Classes.AppGeoPoint { X = 50.84723, Y = -1.0645200000000001 }
};
Classes.AppGeoPoint ReturnVal = getClosestPointOnLines(YourLocation, AreaCheck);
Console.WriteLine("X " + ReturnVal.X);
Console.WriteLine("Y " + ReturnVal.Y);
ReturnVal.X and ReturnVal.Y will return the closest points latitude and longitude.
Hopefully, this may come in helpful to others.

moving a curve by inverse slope of each point without overlap

I am trying to draw curves a specified distance away from a curve. Kind of like the sides of roads are always a set distance away from the yellow lines in the center. I have code to do this, however, when done using my code it ends up with overlap in one of the curves.
Here is my code:
for (int i = 0; i < curves.Count; i++)
{
for (float j = 0; j < 1; j += .001f)
{
Vector2 temp = Vector2.CatmullRom(curves[i].Points[0], curves[i].Points[1], curves[i].Points[2], curves[i].Points[3], j);
if (mid.Count != 0)
{
if (temp != mid[mid.Count - 1])
{
mid.Add(temp);
}
else Console.WriteLine(temp == mid[mid.Count - 1]);
}
else mid.Add(temp);
}
}
for (int i = 0; i < mid.Count; i++)
{
if (i == 0)
{
Vector2 slope = mid[i] - mid[i + 1];
double x = mid[i].X + (12 * Math.Cos(Math.Atan(-(slope.X / slope.Y)))),
y = mid[i].Y + (12 * Math.Sin(Math.Atan(-(slope.X / slope.Y))));
side1.Add(new Vector2((float)x, (float)y));
x = mid[i].X - (12 * Math.Cos(Math.Atan(-(slope.X / slope.Y))));
y = mid[i].Y - (12 * Math.Sin(Math.Atan(-(slope.X / slope.Y))));
side2.Add(new Vector2((float)x, (float)y));
}
else if (i < mid.Count - 1)
{
Vector2 slope1 = mid[i] - mid[i - 1],
slope2 = mid[i + 1] - mid[i];
Vector2 slope = (slope1 + slope2) / 2;
double x = mid[i].X + (12 * Math.Cos(Math.Atan(-(slope.X / slope.Y)))),
y = mid[i].Y + (12 * Math.Sin(Math.Atan(-(slope.X / slope.Y))));
side1.Add(new Vector2((float)x, (float)y));
x = mid[i].X - (12 * Math.Cos(Math.Atan(-(slope.X / slope.Y))));
y = mid[i].Y - (12 * Math.Sin(Math.Atan(-(slope.X / slope.Y))));
side2.Add(new Vector2((float)x, (float)y));
}
else
{
Vector2 slope = mid[i] - mid[i - 1];
double x = mid[i].X + (12 * Math.Cos(Math.Atan(-(slope.X / slope.Y)))),
y = mid[i].Y + (12 * Math.Sin(Math.Atan(-(slope.X / slope.Y))));
side1.Add(new Vector2((float)x, (float)y));
x = mid[i].X - (12 * Math.Cos(Math.Atan(-(slope.X / slope.Y))));
y = mid[i].Y - (12 * Math.Sin(Math.Atan(-(slope.X / slope.Y))));
side2.Add(new Vector2((float)x, (float)y));
}
}
And here is a photo of the result:
Curves with overlap
Any and all help would be appreciated.

GammaLn NameSpace In C#

I purchased the book Numerical Methods, Algorithms and Tools in C# by Waldemar Dos Passos.
On page 463, there is the method:
public static double FactorialLn(int n)
{
if(n < 0)
{
throw new Exception("Input value must be > 0");
}
else
{
return GammaLn(n+1.0);
}
}
I found the namespace where the function GammaLn resides: MicrosoftResearch.Infer.Maths
but Visual Studio 2010 does not recognize it and I was unable to find it in the .NET reference.
Please help me get the program to compile.
Thank you in advance.
I finally found the dource code of the GammaLn method itself here: http://seungwon.tistory.com/9
One does need nothing else when one possesses the very real thing, as Andrey correctly pointed out, but until then ...
I reproduce the method here for future reference, in case the site above stops from functioning.
/// <summary>
/// http://seungwon.tistory.com/9
/// GammaLn函数
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public static double GammaLn(double x)
{
double result = 0.0;
double d1 = -5.772156649015328605195174e-1;
double[,] p1 = {{4.945235359296727046734888e0},{ 2.018112620856775083915565e2},
{2.290838373831346393026739e3},{ 1.131967205903380828685045e4},
{2.855724635671635335736389e4},{ 3.848496228443793359990269e4},
{2.637748787624195437963534e4},{ 7.225813979700288197698961e3}};
double[,] q1 = {{6.748212550303777196073036e1},{ 1.113332393857199323513008e3},
{7.738757056935398733233834e3},{ 2.763987074403340708898585e4},
{5.499310206226157329794414e4},{ 6.161122180066002127833352e4},
{3.635127591501940507276287e4},{ 8.785536302431013170870835e3}};
double d2 = 4.227843350984671393993777e-1;
double[,] p2 = {{4.974607845568932035012064e0},{ 5.424138599891070494101986e2},
{1.550693864978364947665077e4},{ 1.847932904445632425417223e5},
{1.088204769468828767498470e6},{ 3.338152967987029735917223e6},
{5.106661678927352456275255e6},{ 3.074109054850539556250927e6}};
double[,] q2 = {{1.830328399370592604055942e2},{ 7.765049321445005871323047e3},
{1.331903827966074194402448e5},{ 1.136705821321969608938755e6},
{5.267964117437946917577538e6},{ 1.346701454311101692290052e7},
{1.782736530353274213975932e7},{ 9.533095591844353613395747e6}};
double d4 = 1.791759469228055000094023e0;
double[,] p4 = {{1.474502166059939948905062e4},{ 2.426813369486704502836312e6},
{1.214755574045093227939592e8},{ 2.663432449630976949898078e9},
{2.940378956634553899906876e10},{ 1.702665737765398868392998e11},
{4.926125793377430887588120e11},{5.606251856223951465078242e11}};
double[,] q4 = {{2.690530175870899333379843e3},{ 6.393885654300092398984238e5},
{4.135599930241388052042842e7},{ 1.120872109616147941376570e9},
{1.488613728678813811542398e10},{1.016803586272438228077304e11},
{3.417476345507377132798597e11},{ 4.463158187419713286462081e11}};
double[,] c = {{-1.910444077728e-03},{ 8.4171387781295e-04},
{-5.952379913043012e-04},{ 7.93650793500350248e-04},
{-2.777777777777681622553e-03},{ 8.333333333333333331554247e-02},
{ 5.7083835261e-03}};
double eps = 2.2204e-016;
if (x <= 0)
{
//报错!
}
else
{
double xden = 0.0;
double xnum = 0.0;
result = x;
if (x > 0 && x <= eps)
{
result = -Math.Log(x);
}
else if ((x > eps) && (x <= 0.5))
{
double y = x;
xden = 1;
xnum = 0;
for (int i = 0; i < 8; i++)
{
xnum = xnum * y + p1[i, 0];
xden = xden * y + q1[i, 0];
}
result = -Math.Log(y) + (y * (d1 + y * (xnum / xden)));
}
else if ((x > 0.5) && (x <= 0.6796875))
{
double xm1 = (x - 0.5) - 0.5;
xden = 1;
xnum = 0;
for (int i = 0; i < 8; i++)
{
xnum = xnum * xm1 + p2[i, 0];
xden = xden * xm1 + q2[i, 0];
}
result = -Math.Log(x) + xm1 * (d2 + xm1 * (xnum / xden));
}
else if ((x > 0.6796875) && (x <= 1.5))
{
double xm1 = (x - 0.5) - 0.5;
xden = 1;
xnum = 0;
for (int i = 0; i < 8; i++)
{
xnum = xnum * xm1 + p1[i, 0];
xden = xden * xm1 + q1[i, 0];
}
result = xm1 * (d1 + xm1 * (xnum / xden));
}
else if ((x > 1.5) && (x <= 4))
{
double xm2 = x - 2;
xden = 1;
xnum = 0;
for (int i = 0; i < 8; i++)
{
xnum = xnum * xm2 + p2[i, 0];
xden = xden * xm2 + q2[i, 0];
}
result = xm2 * (d2 + xm2 * (xnum / xden));
}
else if ((x > 4) && (x <= 12))
{
double xm4 = x - 4;
xden = -1;
xnum = 0;
for (int i = 0; i < 8; i++)
{
xnum = xnum * xm4 + p4[i, 0];
xden = xden * xm4 + q4[i, 0];
}
result = d4 + xm4 * (xnum / xden);
}
else if (x > 12)
{
double y = x;
double r = c[6, 0];// 等于:double r = repmat(c[6, 0], 1)[0,0];
double ysq = y * y;
for (int i = 0; i < 6; i++)
{
r = r / ysq + c[i, 0];
}
r = r / y;
double corr = Math.Log(y);
double spi = 0.9189385332046727417803297;
result = r + spi - 0.5 * corr + y * (corr - 1);
}
}
return result;
}

Categories