C# sorting file by distance between elements - c#

I have text file that looks something like this
LINE 325,474 195,251 589,821 375,711 Nan Nan Nan
LINE 617,303 578,402 771,724 392,711 Nan Nan Nan
LINE 424,931 472,48 481,203 617,633 Nan Nan Nan
Where first column is basically name of element, second is starting X coordinate, third is starting Y coordinate, fourth and fifth are ending X and Y coordinates, others are not important.
I need to sort them by distance between each line. My code looks something like this:
string[] Text = File.ReadAllLines(OpenFile.Filename);
string[,] Word = new string[Text.Length, 8];
double CurXpos = 0; // for smallest distance set new points (starting from 0,0)
double CurYpos = 0;
string[] word = new string[8];
for (long i = 0; i < Text.Length; i++) // read text
{
string line = Text[i];
for (byte j = 0; j < 8; j++)
{
word = line.Split(' ');
Word[i, j] = word[j]; //store text to 2D array
}
}
StreamWriter FileSorted = new StreamWriter(desired destination);
for (long i = 0; i < Text.Length; i++) // search for minimal distance
{
double X1 = Math.Round(double.Parse(Word[i, 1], System.Globalization.CultureInfo.InvariantCulture), 3); // X start possition to double
double Y1 = Math.Round(double.Parse(Word[i, 2], System.Globalization.CultureInfo.InvariantCulture), 3); //Y , etc.
double X2 = Math.Round(double.Parse(Word[i, 3], System.Globalization.CultureInfo.InvariantCulture), 3);
double Y2 = Math.Round(double.Parse(Word[i, 4], System.Globalization.CultureInfo.InvariantCulture), 3);
double[] XPos = new double[Text.Length]; // array of smallest distances for each line
double[] YPos = new double[Text.Length];
double MinDis1 = Math.Sqrt(Math.Pow(X1 - CurXpos, 2) + Math.Pow(Y1 - CurXpos, 2)); //calculation of the smallest distances
double MinDis2 = Math.Sqrt(Math.Pow(X2 - CurXpos, 2) + Math.Pow(Y2 - CurYpos, 2)); //calculate if end points are closer
long PosMin = 0; //position of line with minimum
double[] AbsMinDis = new double[Text.Length]; // line containing distance data of each line
if (MinDis1 < MinDis2) // if distance of starting coordinate is smaller than ending, save
{
AbsMinDis[i] = MinDis1;
XPos[i] = X1;
YPos[i] = Y1;
}
else if (MinDis2 < MinDis1) // if distance of ending points is smaller, swap starting end endinng points and save line possition
{
AbsMinDis[i] = MinDis2;
XPos[i] = X2;
YPos[i] = Y2;
Word[i, 1] = X2.ToString();
Word[i, 2] = Y2.ToString();
Word[i, 3] = X1.ToString();
Word[i, 4] = Y1.ToString();
}
for (long j = 0; j < Text.Length; j++) //sorting file
{
if (AbsMinDis[i] < AbsMinDis[PosMin])
{
CurXpos = XPos[i];
CurYpos = YPos[i];
string swap = Word[PosMin, j];
Word[PosMin, j] = Word[i, j];
Word[i, j] = swap;
PosMin = i;
}
Now I don't know if I have there any error, or if I don't know how to write it, because it looks like, it does nothing with file
Writing looks like this:
FileSorted.Write(Word[i, 0]);
for (byte k = 1; k < 8; k++)
{
FileSorted.Write(" {0}", Word[i, k]);
}
FileSorted.WriteLine();
}
FileSorted.Close();
Thank you for your time and help.

There is a failure writing to SortedFile in other iterations of i (except the first) because you close the file at the end of iteration:
FileSorted.Close();
if you move FileSorted.Close() after you have done with all the iterations of i, then you will see all lines in the SortedFile.
The line duplication is because when writing to the file where you comment "//sorting file", you are writing the line i times instead of once.
And here you can see the capitalization conventions.

Related

Sorting points by polar angle

I have a problem with sorting points by the angle they create with the X axis. The points look like this
Here is the code I have:
public static List<Point> SortPoints(List<Point> points)
{
List<Point> result = new List<Point>();
List<KeyValuePair<Point, double>> valuePairs = new List<KeyValuePair<Point, double>>();
foreach (var point in points)
{
valuePairs.Add(new KeyValuePair<Point, double>(point, Math.Atan2(point.Y, point.X)));
}
valuePairs = valuePairs.OrderByDescending(x => x.Value).ToList();
foreach (var valuepair in valuePairs)
{
result.Add(valuepair.Key);
}
return result;
}
It should sort points in the way, they close up. It works for most points, but it doesn't for some of them. It crashes mostly on these fragments:
Is my thinking correct for that kind of problem or do I miss something? I am still new to geometry in programming.
C# TRANSLATION
public static List<Point> SortPoints(List<Point> points)
{
double[] pnt = new double[points.Count * 2];
for (int z = 0, ii = 0; z < points.Count; z++, ii += 2)
{
pnt[ii] = points[z].X;
pnt[ii + 1] = points[z].Y;
}
int n2 = pnt.Length;
int n = n2 >> 1;
int[] idx = new int[n];
int i, j, k, i0, i1, e, m;
double a, x0, y0, x1, y1, x, y;
double[] ang = new double[n];
int[] flag = new int[n];
const double deg = Math.PI / 180.0;
const double thr = 0.02 * deg;
for (i = 0; i < n; i++) idx[i] = i + i;
x0 = x1 = pnt[0];
y0 = y1 = pnt[1];
for (i = 0; i < n2;)
{
x = pnt[i]; i++;
y = pnt[i]; i++;
if (x0 > x) x0 = x;
if (x1 < x) x1 = x;
if (y0 > y) y0 = y;
if (y1 < y) y1 = y;
}
x = 0.5 * (x0 + x1);
y = 0.5 * (y0 + y1);
for (i = 0, j = 0; i < n; i++, j += 2)
{
a = Math.Atan2(pnt[j + 1] - y, pnt[j + 0] - x);
ang[i] = a;
}
for (e = 1, j = n; e != 0; j--) // loop until jo swap occurs
for (e = 0, i = 1; i < j; i++) // proces unsorted part of array
if (ang[idx[i - 1] >> 1] > ang[idx[i] >> 1]) // condition if swap needed
{ e = idx[i - 1]; idx[i - 1] = idx[i]; idx[i] = e; e = 1; }
for (i = 0; i < n; i++) flag[i] = 0;
for (e = 0, j = 1, i = 1; i < n; i++)
if (Math.Abs(ang[idx[i] >> 1] - ang[idx[i - 1] >> 1]) < thr)
{ flag[idx[i] >> 1] = j; flag[idx[i - 1] >> 1] = j; e = 1; }
else if (e != 0) { e = 0; j++; }
if (e != 0) j++; m = j;
x = x0 + (0.3 * (x1 - x0));
y = 0.5 * (y0 + y1);
for (i = 0, j = 0; i < n; i++, j += 2)
if (flag[i] != 0) // only for problematic zones no need to recompute finished parts
{
a = Math.Atan2(pnt[j + 1] - y, pnt[j + 0] - x); // this might need handling edge cases of atan2
ang[i] = a;
}
for (k = 0; k < n;)
{
for (; k < n; k++) if (flag[idx[k] >> 1] != 0) // zone start
{
i0 = i1 = k;
for (; k < n; k++) if (flag[idx[k] >> 1] != 0) i1 = k;// // zone end
else break;
// index (bubble) sort idx[] asc by ang[]
if (i0 != i1)
for (e = 1, j = i1 - i0 + 1; e > 0; j--) // loop until jo swap occurs
for (e = 0, i = i0 + 1; i < i0 + j; i++) // proces unsorted part of array
if (ang[idx[i - 1] >> 1] > ang[idx[i] >> 1]) // condition if swap needed
{ e = idx[i - 1]; idx[i - 1] = idx[i]; idx[i] = e; e = 1; } // swap and allow to process array again
// different center for atan2 might reverse the ang order
// so test if start or end of zone is closer to the point before it
j = i0 - 1; if (j < 0) j = n - 1; // 45 deg is never at start or end of data so this should never happen
x = pnt[idx[j] + 0] - pnt[idx[i0] + 0];
y = pnt[idx[j] + 1] - pnt[idx[i0] + 1];
a = (x * x) + (y * y);
x = pnt[idx[j] + 0] - pnt[idx[i1] + 0];
y = pnt[idx[j] + 1] - pnt[idx[i1] + 1];
x = (x * x) + (y * y);
// reverse if not in correct order
if (x < a) for (; i0 < i1; i0++, i1--)
{ j = idx[i0]; idx[i0] = idx[i1]; idx[i1] = j; }
}
}
List<Point> result = new List<Point>();
for (int h = 0; h < pnt.Length - 1; h += 2)
{
result.Add(new Point(pnt[h], pnt[h + 1]));
}
return result;
}
Ok I got it working sorting by atan2 angle by using 2 centers only (no need for 3 as I can detect the problem zones directly from the first center alone). This is the algorithm (shape must not self intersect and angle around selected centers must be monotonic !!!):
compute BBOX (x0,y0,x1,y1) for your data
this is needed to properly compute correct center locations for atan2 usage
compute angle by atan2 for each point using BBOX center as center
the center should be inside your shape so center of BBOX is the obvious choice. However as Yves Daoust pointed out this will not work for arbitrary concave shapes only for those shapes and centers where the angle is monotonic.
sort your points by this angle
detect problematic zones
simply in problematic zones the consequent points after the sort has almost the same angle so just threshold that.
compute atan2 angle for each problem zone with different center
again center must be inside ... and should be shifted in any of the multiple of 90 degrees angle from original center. I chose shift toward x0 by 20% of shape x size. The bigger the shift the more ang difference the problem zones will get.
sort the problem zones by new angle
reverse problem zone order after sort if needed
the shifted center might cause the angle direction reversal in comparison to original angles. So after sort if you compute distance between point before zone and zone first and last point if the last point of zone is closer it means you need to reverse the zone points order.
Here preview of output:
Here C++/OpenGL/VCL code for this:
//---------------------------------------------------------------------------
#include <vcl.h>
#include <math.h>
#pragma hdrstop
#include "Unit1.h"
#include "gl_simple.h"
#include "data.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
const int n2=sizeof(pnt)/sizeof(pnt[0]); // size of pnt[]
const int n=n2>>1; // point in pnt[]
int idx[n]; // index sort
int ix=1055; // just debug X cursor on mouse wheel
//---------------------------------------------------------------------------
void compute()
{
int i,j,k,i0,i1,e,m;
float a,x0,y0,x1,y1,x,y;
float ang[n]; // atan2 angles per point
int flag[n]; // 0 or problem zone ix per point
const float deg=M_PI/180.0;
const float thr=0.02*deg;
// shuffle input data for debug as its already ordered
for (i=0;i<n2;)
{
j=Random(n2)&0xFFFFFFFE;
a=pnt[i]; pnt[i]=pnt[j]; pnt[j]=a; i++; j++;
a=pnt[i]; pnt[i]=pnt[j]; pnt[j]=a; i++; j++;
}
// init index sort table
for (i=0;i<n;i++) idx[i]=i+i;
// compute BBOX of data
x0=x1=pnt[0];
y0=y1=pnt[1];
for (i=0;i<n2;)
{
x=pnt[i]; i++;
y=pnt[i]; i++;
if (x0>x) x0=x;
if (x1<x) x1=x;
if (y0>y) y0=y;
if (y1<y) y1=y;
}
// compute atan2 for center set to center of BBOX
x=0.5*(x0+x1);
y=0.5*(y0+y1);
for (i=0,j=0;i<n;i++,j+=2)
{
a=atan2(pnt[j+1]-y,pnt[j+0]-x); // this might need handling edge cases of atan2
ang[i]=a;
}
// index (bubble) sort idx[] asc by ang[]
for (e=1,j=n;e;j--) // loop until no swap occurs
for (e=0,i=1;i<j;i++) // process unsorted part of array
if (ang[idx[i-1]>>1]>ang[idx[i]>>1]) // condition if swap needed
{ e=idx[i-1]; idx[i-1]=idx[i]; idx[i]=e; e=1; } // swap and allow to process array again
// detect/label problematic zones m = number of zones +1
for (i=0;i<n;i++) flag[i]=0;
for (e=0,j=1,i=1;i<n;i++)
if (fabs(ang[idx[i]>>1]-ang[idx[i-1]>>1])<thr)
{ flag[idx[i]>>1]=j; flag[idx[i-1]>>1]=j; e=1; }
else if (e){ e=0; j++; }
if (e) j++; m=j;
// compute atan2 for center shifted toward x0
// so it still inside but not too close to (0,0)
// so there is some ang diference on problematic zones
x=x0+(0.3*(x1-x0));
y=0.5*(y0+y1);
for (i=0,j=0;i<n;i++,j+=2)
if (flag[i]) // only for problematic zones no need to recompute finished parts
{
a=atan2(pnt[j+1]-y,pnt[j+0]-x); // this might need handling edge cases of atan2
ang[i]=a;
}
// loop through problematic zones
for (k=0;k<n;)
{
for (;k<n;k++) if (flag[idx[k]>>1]) // zone start
{
i0=i1=k;
for (;k<n;k++) if (flag[idx[k]>>1]) i1=k; // zone end
else break;
// index (bubble) sort idx[] asc by ang[]
if (i0!=i1)
for (e=1,j=i1-i0+1;e;j--) // loop until no swap occurs
for (e=0,i=i0+1;i<i0+j;i++) // process unsorted part of array
if (ang[idx[i-1]>>1]>ang[idx[i]>>1]) // condition if swap needed
{ e=idx[i-1]; idx[i-1]=idx[i]; idx[i]=e; e=1; } // swap and allow to process array again
// different center for atan2 might reverse the ang order
// so test if start or end of zone is closer to the point before it
j=i0-1; if (j<0) j=n-1; // 45 deg is never at start or end of data so this should never happen
x=pnt[idx[j]+0]-pnt[idx[i0]+0];
y=pnt[idx[j]+1]-pnt[idx[i0]+1];
a=(x*x)+(y*y);
x=pnt[idx[j]+0]-pnt[idx[i1]+0];
y=pnt[idx[j]+1]-pnt[idx[i1]+1];
x=(x*x)+(y*y);
// reverse if not in correct order
if (x<a) for (;i0<i1;i0++,i1--)
{ j=idx[i0]; idx[i0]=idx[i1]; idx[i1]=j; }
}
}
}
//---------------------------------------------------------------------------
void gl_draw()
{
int i,j;
float a,da=1.0/float(n-1),x,y,r;
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
// set view to 2D
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(1.0/120.0,1.0/120.0,1.0);
// render points from list
glBegin(GL_POINTS);
// glBegin(GL_LINE_STRIP);
// glBegin(GL_TRIANGLE_FAN);
glColor3f(0.0,0.0,0.0);
glVertex2f(0.0,0.0);
for (a=0.0,i=0;i<n;i++,a+=da)
{
glColor3f(a,a,a);
glVertex2fv(pnt+idx[i]);
}
glEnd();
// render debug index (on mouse wheel)
x=pnt[idx[ix]+0];
y=pnt[idx[ix]+1];
r=5.0;
glBegin(GL_LINES);
glColor3f(0.0,1.0,0.0);
glVertex2f(x-r,y-r);
glVertex2f(x+r,y+r);
glVertex2f(x-r,y+r);
glVertex2f(x+r,y-r);
glEnd();
glFinish();
SwapBuffers(hdc);
Form1->Caption=ix;
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
{
// Init of program
gl_init(Handle); // init OpenGL
compute();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
// Exit of program
gl_exit();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
// repaint
gl_draw();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
// resize
gl_resize(ClientWidth,ClientHeight);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta, TPoint &MousePos, bool &Handled)
{
Handled=true;
int dix=1; if (Shift.Contains(ssShift)) dix=10;
if (WheelDelta>0){ ix+=dix; if (ix>=n) ix= 0; }
if (WheelDelta<0){ ix-=dix; if (ix< 0) ix=n-1; }
gl_draw();
}
//---------------------------------------------------------------------------
Just ignore the VCL and OpenGL stuff. The only important stuff here is the function compute() which works as described above. The global variables just above it. I used index sort however so the points order is not changed at all instead idx[i] holds the index of i-th point in the input data. I wanted to keep this as simple as I could so no dynamic allocations nor containers or funny stuff... I used your data as input in form:
float pnt[]=
{
-98.622,0.4532042,
-98.622,1.64291,
-98.612097,3.0877569,
...
-98.618994,-3.2649391,
-98.6260115,-1.9205891
};
The gl_simple.h I used for OpenGL can be found here:
complete GL+GLSL+VAO/VBO C++ example
I tested this by using the cursor (green cross on image) and mouse wheel through the whole shape looking for jumping back and forward ... In previous versions I got the flag[] array as global and rendered different colors for the problem zones so I can debug directly them and not looking for whole shape again and again ... Also I used bubble sort ... in case you got huge data use quick sort instead... however this data you provided is computed instantly on my old computer so I didn't bother to add recursion.
For arbitrary concave non self-intersecting shapes you need to use different approach like for example connected component analysis:
for each point compute its 2 nearest neighbor points
this is very slow and should be speed-ed up by using spatial sorting of points to lower the complexity.
in case of very non uniform sampling the two closest points should not lie on or near the same direction!!! So dot between their unit direction should be as far from +1.0 as it can.
select any start point and add it to output
select one of its yet unused neighbors and add it to output
set link between selected and its predecessing point as used.
loop #4 until you get to the starting point again

Matrix Multiplication returning wrong value

I am calculating values by using weights and bias from MATLAB trained ANN. trying to code a sigmoid simulation equation, but for some reason C# calculations vary too much than that of MATLAB. i.e. error is too high. I tried to check each step of the equation and found out the specific part that is creating the problem (Emphasized part), but I don't know how to solve this issue, if someone could help, would be a huge favour.
1+(purelin(net.LW{2}×(tansig(net.IW{1}×(1-(abs(2×([inputs]-1)))))+net.b{1}))+net.b{2}))/2
//Normalization of Data
public double Normalization(double x, double xMAx, double xMin)
{
double xNorm = 0.0;
xNorm = (x - xMin) / (xMAx - xMin);
if (xNorm < 0)
xNorm = 0;
if (xNorm > 1)
xNorm = 1;
xNorm = Math.Round(xNorm, 4);
return xNorm;
}
// Equation to calculate ANN based Output Values
public double MetrixCalc(double[] Pn, double[,] W1, double[] W2, double[] b1, double b2, double maxValue, double minValue)
{
double FinalValue = 0;
double[] PnCalc1 = new double[Pn.Length];
double[] PnCalc2 = new double[W1.Length / Pn.Length];
for (int i = 0; i < Pn.Length; i++)
{
PnCalc1[i] = 1 - Math.Abs(2 * (Pn[i] - 1));
}
for (int i = 0; i < (W1.Length / Pn.Length); i++)
{
double PnCalc = 0.0;
for (int j = 0; j < Pn.Length; j++)
{
PnCalc = PnCalc + (W1[i, j] * PnCalc1[j]);
}
PnCalc2[i] = PnCalc;
}
for (int i = 0; i < PnCalc2.Length; i++)
{
//PnCalc2[i] = Math.Tanh(PnCalc2[i] + b1[i]);
PnCalc2[i] = PnCalc2[i] + b1[i];
PnCalc2[i] = 2.0 / (1 + Math.Exp(-2 * (PnCalc2[i]))) - 1;
PnCalc2[i] = Math.Round(PnCalc2[i], 4);
}
double FinalCalc = 0.0;
for (int i = 0; i < PnCalc2.Length; i++)
{
*FinalCalc = FinalCalc + (W2[i] * (PnCalc2[i]));*
//FinalValue = FinalCalc;
}
FinalValue = FinalCalc + b2;
FinalValue = 1 + FinalValue;
FinalValue = (1 + FinalValue) / 2.0;
FinalValue = (FinalValue * (maxValue - minValue)) + minValue;
FinalValue = Math.Round(FinalValue, 4);
FinalValue = Math.Abs(FinalValue);
return FinalValue;
}
Problem is solved.
Problem was with the weights matrix copied from MATLAB. debugging mode saved my life. :)

Algorithm to scale down YUV 4:2:2

Trying to write an efficient algorithm to scale down YUV 4:2:2 by a factor of 2 - and which doesn't require a conversion to RGB (which is CPU intensive).
I've seen plenty of code on stack overflow for YUV to RGB conversion - but only an example of scaling for YUV 4:2:0 here which I have started based my code on. However, this produces an image which is effectively 3 columns of the same image with corrupt colours, so something is wrong with the algo when applied to 4:2:2.
Can anybody see what is wrong with this code?
public static byte[] HalveYuv(byte[] data, int imageWidth, int imageHeight)
{
byte[] yuv = new byte[imageWidth / 2 * imageHeight / 2 * 3 / 2];
int i = 0;
for (int y = 0; y < imageHeight; y += 2)
{
for (int x = 0; x < imageWidth; x += 2)
{
yuv[i] = data[y * imageWidth + x];
i++;
}
}
for (int y = 0; y < imageHeight / 2; y += 2)
{
for (int x = 0; x < imageWidth; x += 4)
{
yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
i++;
yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x + 1)];
i++;
}
}
return yuv;
}
A fast way to generate a low quality thumbnail would be to discard half of the data in each dimension.
We break the image in 4x2 grid of pixels - each pair of pixels in the grid is represented by 4 bytes. In the down-scaled image, we take the color values for the first 2 pixels in the grid by copying the first 4 bytes, whilst discarding the other 12 bytes worth of data.
This scaling can be generalized to any power of 2 (1/2, 1/4, 1/8, ...) - this method is quick because it doesn't use any interpolation. This will give a lower quality image which appears blocky however - for better results consider some sampling approach.
public static byte[] FastResize(
byte[] data,
int imageWidth,
int imageHeight,
int scaleDownExponent)
{
var scaleDownFactor = (uint)Math.Pow(2, scaleDownExponent);
var outputImageWidth = imageWidth / scaleDownFactor;
var outputImageHeight = imageHeight / scaleDownFactor;
// 2 bytes per pixel.
byte[] yuv = new byte[outputImageWidth * outputImageHeight * 2];
var pos = 0;
// Process every other line.
for (uint pixelY = 0; pixelY < imageHeight; pixelY += scaleDownFactor)
{
// Work in blocks of 2 pixels, we discard the second.
for (uint pixelX = 0; pixelX < imageWidth; pixelX += 2*scaleDownFactor)
{
// Position of pixel bytes.
var start = ((pixelY * imageWidth) + pixelX) * 2;
yuv[pos] = data[start];
yuv[pos + 1] = data[start + 1];
yuv[pos + 2] = data[start + 2];
yuv[pos + 3] = data[start + 3];
pos += 4;
}
}
return yuv;
}
I assume that the original data is in the following order (as it seems so from your example code): First there are the luminance (Y) values of the pixels of the image (size = imageWidth*imageHeight bytes). After that there are the chrominance components UV, s.t., the values for a single pixel are given after each other. This means that the total size of the original image is 3*size.
Now for 4:2:2 subsampling means that every other value of the horizontal chrominance component are discarded. This reduces the data to size size + 0.5*size + 0.5*size = 2*size, i.e., luminance is kept completely and both chrominance components are divided to half. Therefore, the result image should be allocated as:
byte[] yuv = new byte[2*imageWidth*imageHeight];
As the first part of the image is copied in full the first loop becomes:
int i = 0;
for (int y = 0; y < imageHeight; y++)
{
for (int x = 0; x < imageWidth; x++)
{
yuv[i] = data[y * imageWidth + x];
i++;
}
}
Because this just copies the beginning of data this can be simplified to
int size = imageHeight*imageWidth;
int i = 0;
for (; i < size; i++)
{
yuv[i] = data[i];
}
Now to copy the rest we need to skip every other horizontal coordinate
for (int y = 0; y < imageHeight; y++)
{
for (int x = 0; x < imageWidth; x += 2) // +2 skip each other horizontal component
{
yuv[i] = data[size + y*2*imageWidth + 2*x];
i++;
yuv[i] = data[size + y*2*imageWidth + 2*x + 1];
i++;
}
}
The factor two in data-array index is needed because there are 2 bytes for each pixel (both chrominance components), so each "row" has 2*imageWidth bytes of data.

C# I want to sort 2D array, but my code only rewrites it

I did not find this question, so i Would like to ask. I am sorting 2D array using this code
for (long j = 0; j < Text.Length; j++)
{
if (AbsMinDis[i] < AbsMinDis[PosMin])
{
CurXpos = XPos[i];
CurYpos = YPos[i];
string swap = Word[PosMin, j];
Word[PosMin, j] = Word[i, j];
Word[i, j] = swap;
PosMin = i;
}
}
then, i am writing it like that:
for (long i = 0; i < Text.Length; i++)
{
FileSorted.Write(Word[i, 0]);
for (byte k = 1; k < 8; k++)
{
FileSorted.Write(" {0}", Word[i, k]);
}
FileSorted.WriteLine();
}
FileSorted.Close();
what it does is that it rewrite code in exact order as original. I am using this code to find the closest distance between elements AbsMinDis and then sort them and write into file.
Thank you for your help
Variables
StreamWriter FileSorted = new StreamWriter("C://Users//Tomas//Desktop//Bakalárka//Fiel test//Fiel test//tmp//Data.txt");
long PosMin = 0; //position of line with minimum
for (long i = 0; i < Text.Length; i++) // search for minimal distance
{
double X1 = Math.Round(double.Parse(Word[i, 1], System.Globalization.CultureInfo.InvariantCulture), 3); // X start possition to double
double Y1 = Math.Round(double.Parse(Word[i, 2], System.Globalization.CultureInfo.InvariantCulture), 3); //Y , etc.
double X2 = Math.Round(double.Parse(Word[i, 3], System.Globalization.CultureInfo.InvariantCulture), 3);
double Y2 = Math.Round(double.Parse(Word[i, 4], System.Globalization.CultureInfo.InvariantCulture), 3);
double[] XPos = new double[Text.Length]; // array of smallest distances for each line
double[] YPos = new double[Text.Length];
double MinDis1 = Math.Sqrt(Math.Pow(X1 - CurXpos, 2) + Math.Pow(Y1 - CurXpos, 2)); //calculation of the smallest distances
double MinDis2 = Math.Sqrt(Math.Pow(X2 - CurXpos, 2) + Math.Pow(Y2 - CurYpos, 2)); //calculate if end points are closer
double[] AbsMinDis = new double[Text.Length]; // line containing distance data of each line
if (MinDis1 < MinDis2) // if distance of starting coordinate is smaller than ending, save

c# feed a method with x and y values from a chart (polynomial calculation)

I have got this method to get a polynomial with my desired degree:
public static double[] Polyfit(double[] x, double[] y, int degree)
{
// Vandermonde matrix
var v = new DenseMatrix(x.Length, degree + 1);
for (int i = 0; i < v.RowCount; i++)
for (int j = 0; j <= degree; j++) v[i, j] = Math.Pow(x[i], j);
var yv = new DenseVector(y).ToColumnMatrix();
QR qr = v.QR();
// Math.Net doesn't have an "economy" QR, so:
// cut R short to square upper triangle, then recompute Q
var r = qr.R.SubMatrix(0, degree + 1, 0, degree + 1);
var q = v.Multiply(r.Inverse());
var p = r.Inverse().Multiply(q.TransposeThisAndMultiply(yv));
Console.WriteLine(p.Column(0).ToString());
return p.Column(0).ToArray();
}
How can I feed the method above with values from my chart (x and y)?
chart.Series[0].Points.... ?
I think you need this:
chart1.Series[0].YValueMembers
chart1.Series[0].XValueMember
The Points property is a getter, so you cannot set a new instance of DataPointCollection to it. You should however be able to access methods on the current DataPointCollection.
You could try something along the lines of:
chart.Series[0].Points.AddXY(double, double)
You would then iterate the array(s) and set the points manually.
MSDN DataPointCollection for more information.
A working solution is:
////generate polynomial of degree 4 fiting to the points
double[] arrayX = new double[chart.Series[0].Points.Count()];
double[] arrayY = new double[chart.Series[0].Points.Count()];
double[] arrayResult = { };
for (int i = 0; i < chart.Series[0].Points.Count(); i++)
{
arrayX[i] = chart.Series[0].Points[i].XValue;
arrayY[i] = chart.Series[0].Points[i].YValues[0];
}
arrayResult = Polyfit(arrayX, arrayY, 4);
foreach (double element in arrayResult)
{
MessageBox.Show(element.ToString());
}
double functionVarE = arrayResult[0];
double functionVarD = arrayResult[1];
double functionVarC = arrayResult[2];
double functionVarB = arrayResult[3];
double functionVarA = arrayResult[4];
double equationVar = 0;
//prepare the function series in the graph
if (chart.Series.IndexOf("function") < 0)
chart.Series.Add("function");
chart.Series[2].Points.Clear();
chart.Series[2].ChartType = SeriesChartType.Line;
for (int x = -500; x < 1000; x++) //hardcoding
{
equationVar = functionVarA * (Math.Pow(x, 4)) + functionVarB * (Math.Pow(x, 3)) + functionVarC * (Math.Pow(x, 2)) + functionVarD * x + functionVarE;
chart.Series[2].Points.AddXY(Convert.ToDouble(x), equationVar);
}
This is a working solution I coded. If you see any improvement feel free to tell me!

Categories