private static int IntepolateValue(int val1, int val2, float delta, string mode) { switch (mode) { case BridgeInterpolationMode.HIGHEST: case BridgeInterpolationMode.BRIGHTNESS_HIGHEST: return(Math.Max(val1, val2)); case BridgeInterpolationMode.LOWEST: case BridgeInterpolationMode.BRIGHTNESS_LOWEST: return(Math.Min(val1, val2)); case BridgeInterpolationMode.LINEAR: return((int)Math.Round(InterpolationTools.Linear(val1, val2, delta))); case BridgeInterpolationMode.IN_SINE: return((int)Math.Round(InterpolationTools.EaseInSine(val1, val2, delta))); case BridgeInterpolationMode.OUT_SINE: return((int)Math.Round(InterpolationTools.EaseOutSine(val1, val2, delta))); case BridgeInterpolationMode.IN_OUT_SINE: return((int)Math.Round(InterpolationTools.EaseInOutSine(val1, val2, delta))); default: throw new Exception("DrawBezierPathMode.IntepolateValue: \"" + mode + "\" mode is not supported!"); } }
// This generates the vertices to split the line with, from start to end private List <Vector2D> GenerateCurve(Linedef line) { // Fetch settings from the panel bool fixedcurve = panel.FixedCurve; int vertices = Math.Min(panel.Vertices, (int)Math.Ceiling(line.Length / 4)); int distance = panel.Distance; int angle = (!fixedcurve && distance == 0 ? Math.Max(5, panel.Angle) : panel.Angle); float theta = Angle2D.DegToRad(angle); if (distance < 0) { theta = -theta; //mxd } // Make list List <Vector2D> points = new List <Vector2D>(vertices); float segDelta = 1.0f / (vertices + 1); //mxd Vector2D linecenter = line.GetCenterPoint(); //mxd //mxd. Special cases... if (angle == 0) { for (int v = 1; v <= vertices; v++) { float x = (line.Length * segDelta) * (vertices - v + 1) - line.Length * 0.5f; // Line segment coord // Rotate and transform to fit original line Vector2D vertex = new Vector2D(x, 0).GetRotated(line.Angle + Angle2D.PIHALF) + linecenter; points.Add(vertex); } } else { //Added by Anders Åstrand 2008-05-18 //The formulas used are taken from http://mathworld.wolfram.com/CircularSegment.html //c and theta are known (length of line and angle parameter). d, R and h are //calculated from those two //If the curve is not supposed to be a circular segment it's simply deformed to fit //the value set for distance. //The vertices are generated to be evenly distributed (by angle) along the curve //and lastly they are rotated and moved to fit with the original line //calculate some identities of a circle segment (refer to the graph in the url above) float c = line.Length; float d = (c / (float)Math.Tan(theta / 2)) / 2; float R = d / (float)Math.Cos(theta / 2); float h = R - d; float yDeform = (fixedcurve ? 1 : distance / h); float xDelta = Math.Min(1, yDeform); //mxd for (int v = 1; v <= vertices; v++) { //calculate the angle for this vertex //the curve starts at PI/2 - theta/2 and is segmented into vertices+1 segments //this assumes the line is horisontal and on y = 0, the point is rotated and moved later float a = (Angle2D.PI - theta) / 2 + v * (theta / (vertices + 1)); //calculate the coordinates of the point, and distort the y coordinate //using the deform factor calculated above float xr = (float)Math.Cos(a) * R; //mxd. Circle segment coord float xl = (line.Length * segDelta) * (vertices - v + 1) - line.Length * 0.5f; // mxd. Line segment coord float x = InterpolationTools.Linear(xl, xr, xDelta); //mxd float y = ((float)Math.Sin(a) * R - d) * yDeform; //rotate and transform to fit original line Vector2D vertex = new Vector2D(x, y).GetRotated(line.Angle + Angle2D.PIHALF) + linecenter; points.Add(vertex); } } // Done return(points); }