在抛物线C#上找到对称点

时间:2017-05-16 17:01:24

标签: c# list linq indexing

我搜索过很多帖子,找不到我需要的内容。我看到找到与目标最接近的数字的解决方案,但我需要找到该数字的数字,然后可以选择不完全对称的“抛物线”形状数据集另一侧的最接近数字。我基本上使用:

List<int> list = new List<int> { 2, 5, 7, 10 };
int number = 9;

int closest = list.Aggregate((x,y) => Math.Abs(x-number) < Math.Abs(y-
number) ? x : y);

这就是我找到第一个目标号码的方法。现在我需要找到一个值几乎相等的第二个数字,但是在抛物线的另一边(我真的需要这些数字的索引,但我可以将这些数字放在一起)。我的方法不断出现一个数字。基本上我需要移动到抛物线上的近似对称索引以选择等效数字。为了说明这一点,我正在计算波束宽度,即特定点处抛物线边缘之间的距离。请告诉我这是否有意义,如果我需要在你投票之前解释更多。我做了大量的研究和测试。我很难提供更多代码,因为它来自一个没有互联网的价值500,000美元的测试系统,所以我无法复制和粘贴我的代码。如果需要更多代码,我可以去额外的院子,只是试图避免损害昂贵的嵌入式Windows系统。

以下是我需要更进一步的相关文章 located here

修改添加完整代码:

fileName = textBox10.Text;
            SetupControlState(true);


            if (comboBox2.SelectedIndex == 0)
            {
                cent = false;
            }
            else if (comboBox2.SelectedIndex == 1)
            {
                cent = true;
            }
           testHPositions = new List<double>();
           testHMeasurements = new List<double>();

            testVPositions = new List<double>();
            testVMeasurements = new List<double>();

            double horzRange = Double.Parse(textBox12.Text);
            double vertRange = Double.Parse(textBox11.Text);
            double refGain = Double.Parse(textBox14.Text);
            double stepSize = Double.Parse(textBox13.Text);
            testBorePos = new double[1, 2];
            _worker = new BackgroundWorker();
            _worker.WorkerSupportsCancellation = true;

            testBoreRun.Enabled = false;
            button2.Enabled = true;
            _worker.RunWorkerAsync();

            _worker.DoWork += new DoWorkEventHandler((state, args) =>
            {
                //  try
                // {
                dev1 = new VisaDevice("inst0", "TCPIP0::192.168.0.10::inst0::INSTR"); //textBox1.Text);
                if (!cent)
                {
                    Double startfreq = double.Parse(textBox2.Text) * 1000000000;
                    Double stopfreq = double.Parse(textBox1.Text) * 1000000000;

                    dev1.SendBlocking("FREQ:STAR " + startfreq.ToString(), true);
                    string responseFreq = "";
                    dev1.QueryBlocking("FREQ:STAR?", ref responseFreq, true);
                    dev1.SendBlocking("FREQ:STOP " + stopfreq.ToString(), true);

                    dev1.QueryBlocking("FREQ:STOP?", ref responseFreq, true);
                }

                else if (cent)
                {
                    Double freq = double.Parse(textBox9.Text) * 1000000000;
                    Double span = double.Parse(textBox8.Text) * 1000000000;
                    dev1.SendBlocking("FREQ:CENT " + freq.ToString(), true);
                    string responseFreq = "";
                    dev1.QueryBlocking("FREQ:CENT?", ref responseFreq, true);
                    dev1.SendBlocking("FREQ:SPAN " + span.ToString(), true);
                    dev1.QueryBlocking("FREQ:SPAN?", ref responseFreq, true);
                    //   this.InvokeEx(f => f.stringReadTextBox.AppendText("Spectrum Analyzer Connected" + Environment.NewLine));
                }
                string progID;
                Util U = new Util();
                progID = "ASCOM.iOptron.Telescope";
                if (progID != "")
                {
                    PauseClass pause;
                    pause = new PauseClass();
                    Telescope T = new Telescope(progID);
                    T.Connected = true;
                    pause.Pause(5000);
                    T.Tracking = false;
                    T.TargetDeclination = 1;
                    T.TargetRightAscension = 1;
                    this.InvokeEx(f => f.stringReadTextBox.AppendText("  Connected to " + progID + Environment.NewLine));
                    this.InvokeEx(f => f.stringReadTextBox.AppendText("  Connected to Spectrum Analyzer" + Environment.NewLine));

                    T.SlewToAltAz(180.00, 45 - vertRange);
                    double Alt = T.Altitude;
                    for (int i = 0; i < ((vertRange * 2) / stepSize) + 1; i++)
                    {
                        if (_worker.CancellationPending)
                            break;

                        T.SlewToAltAz(180, Alt + stepSize * i);
                        this.InvokeEx(f => f.stringReadTextBox.AppendText("Test Altitude = " +(T.Altitude - 45).ToString("F") + Environment.NewLine));
                        testVPositions.Add(T.Altitude);
                        dev1.SendBlocking("INIT", true); //Start single measurement

                        string respOPC = "", responseState = "", responseMarkerY = "";
                        dev1.QueryBlocking("*OPC?", ref respOPC, true); //Wait for operation complete
                        dev1.QueryBlocking("STAT:QUES:MEAS?", ref responseState, true); //Check State
                        dev1.QueryBlocking("CALC:MARK:Y?", ref responseMarkerY, true); // Get the result
                        this.InvokeEx(f => f.stringReadTextBox.AppendText(responseMarkerY + Environment.NewLine));
                        testVMeasurements.Add(Double.Parse(responseMarkerY));

                        if (testVMeasurements.Count > ((vertRange * 2) / stepSize))
                        {


                            this.InvokeEx(f => f.stringReadTextBox.AppendText("Vertical Scanning Is Complete!" + Environment.NewLine));

                            double maxVamp = testVMeasurements.Max();
                            int index2 = testVMeasurements.IndexOf(testVMeasurements.Max());
                            double maxVPos = testVPositions[index2];
                            testBorePos[0, 1] = maxVPos;
                            this.InvokeEx(f => f.stringReadTextBox.AppendText("Vertical Max Amplitude = " + maxVamp + Environment.NewLine));
                            this.InvokeEx(f => f.stringReadTextBox.AppendText("Vertical Position of  Max Amplitude = " + (maxVPos - 45).ToString("F") + Environment.NewLine));



                        }
                    }

                    if (!_worker.CancellationPending)
                    {
                        T.SlewToAltAz(180.00 - horzRange, testBorePos[0, 1]);
                    }

                    double Az = T.Azimuth;
                    for (int i = 0; i < ((horzRange * 2) / stepSize) + 1; i++)
                    {
                        if (_worker.CancellationPending)
                            break;
                        if (vertRange > 20)
                        {

                            this.InvokeEx(f => f.stringReadTextBox.AppendText("Vertical Range Cannot Be Greater than +/- 20 Degreez" + Environment.NewLine));
                            break;
            }
                        T.SlewToAltAz(Az + stepSize * i,testBorePos[0,1]);

                        this.InvokeEx(f => f.stringReadTextBox.AppendText("Test Azimuth = " + (T.Azimuth-180).ToString("F") + Environment.NewLine));

                        testHPositions.Add(T.Azimuth);
                        dev1.SendBlocking("INIT", true); //Start single measurement
                        string respOPC = "", responseState = "", responseMarkerY = "", responseMarkerX = "";
                        // string responseFreq = "";
                        dev1.QueryBlocking("*OPC?", ref respOPC, true); //Wait for operation complete
                        dev1.QueryBlocking("STAT:QUES:MEAS?", ref responseState, true); //Check State
                        dev1.QueryBlocking("CALC:MARK:Y?", ref responseMarkerY, true); // Get the result
                        dev1.QueryBlocking("CALC:MARK:X?", ref responseMarkerX, true); // Get the result
                        this.InvokeEx(f => f.stringReadTextBox.AppendText(responseMarkerY + Environment.NewLine));
                        testHMeasurements.Add(Double.Parse(responseMarkerY));

                        if (testHMeasurements.Count > ((horzRange * 2) / stepSize))
                        {
                            _worker.CancelAsync();
                            stop = false;
                            this.InvokeEx(f => f.testBoreRun.Enabled = true);
                            this.InvokeEx(f => f.button2.Enabled = false);
                            this.InvokeEx(f => f.stringReadTextBox.AppendText("Horizontal Scanning Is Complete!" + Environment.NewLine));
                            double maxHamp =testHMeasurements.Max();
                            int index =testHMeasurements.IndexOf(testHMeasurements.Max());
                            double maxHPos =testHPositions[index];
                            testBorePos[0, 0] = maxHPos;
                            this.InvokeEx(f => f.stringReadTextBox.AppendText("Horizontal Max Amplitude = " + maxHamp + Environment.NewLine));
                            this.InvokeEx(f => f.stringReadTextBox.AppendText("Horizontal Position of  Max Amplitude = " +( maxHPos-180).ToString("F") + Environment.NewLine));
                            this.InvokeEx(f => f.stringReadTextBox.AppendText("Antenna Under Test Peak Amplitude located at (" + (testBorePos[0, 0] - 180).ToString("F") + " , " + (testBorePos[0, 1] - 45).ToString("F") + ")" + Environment.NewLine));
                            this.InvokeEx(f => f.SetupControlState(false));

                            T.SlewToAltAz(testBorePos[0, 0], testBorePos[0, 1]);
                            dev1.SendBlocking("INIT", true); //Start single measurement
                            maxAmpTest = new double();
                            string respOPC2 = "", responseState2 = "", responseMarkerY2 = "";
                            dev1.QueryBlocking("*OPC?", ref respOPC2, true); //Wait for operation complete
                            dev1.QueryBlocking("STAT:QUES:MEAS?", ref responseState2, true); //Check State
                            dev1.QueryBlocking("CALC:MARK:Y?", ref responseMarkerY2, true); // Get the result
                            maxAmpTest = Double.Parse(responseMarkerY2);
                            double target = maxAmpTest - 3;

这是我被困的地方:

                            //    int indexbeam = testHMeasurements.IndexOf(target);
                            // indexList = testHMeasurements.IndexOf(testHMeasurements.FindAll(s => s.Equals(target)).First());
                            double closest = testHMeasurements.Aggregate((x, y) => Math.Abs(x - target) < Math.Abs(y - target) ? x : y);
                            var result = Enumerable.Range(0, testHMeasurements.Count).Where(j => testHMeasurements[j] ==closest).ToList();
                         // int beamIndex1 = testHMeasurements.IndexOf(testHMeasurements.OrderBy(item => Math.Abs(target - item)).First());
                          //  int beamIndex2 = testHMeasurements.IndexOf(testHMeasurements.OrderBy(item => Math.Abs((beamIndex1 + 1) - item)).First());
                            double beam1 =( testHPositions[result[0]]) - 180;
                            double beam2 = (testHPositions[result[1]]) - 180;
                            beamWidth = Math.Abs(beam1) + Math.Abs(beam2);

                            this.InvokeEx(f => f.stringReadTextBox.AppendText("Antenna Under Test Amplitude = " + responseMarkerY2 + Environment.NewLine));
                            this.InvokeEx(f => f.stringReadTextBox.AppendText(" Antenna Under Test Gain = " + (maxAmpTest - refAmp + refGain) + Environment.NewLine));
                            this.InvokeEx(f => f.stringReadTextBox.AppendText(" Antenna Under Test Beam Width = " +beamWidth.ToString("F") + Environment.NewLine));
                            testGain = maxAmpTest - refAmp + refGain;
                        }


                    }

                    T.Connected = false;
                    T.Dispose();
                    dev1.Dispose();
                    if (_worker.CancellationPending)
                    {
                        Save();

                        // Cleanup Excel resources
                        GC.Collect();
                        GC.WaitForPendingFinalizers();
                    }
                }
            });

2 个答案:

答案 0 :(得分:2)

首先,你必须找到抛物线。由于您的数据仅接近抛物线,因此需要使用名为Quadratic RegressionPolynomial Regression的统计方法来查找等式abc的参数

  

y = ax 2 + bx + c

定义抛物线,最适合点数给出的数据集

  

(x i ,y i

使用数学库或谷歌搜索算法。

一旦得到抛物线,确定抛物线的对称轴,即抛物线的find the x-value of where the minimum或最大值(如果抛物线是颠倒的)。

  

x s = -b / 2a

现在,一旦你有一个给定的x值,你可以通过在x s上镜像x来找到抛物线另一侧的一个

  

X&#39; = 2x s - x

这是二维抛物线的解释。如果你有一个三维抛物线,即一个Paraboloid原则保持不变,但数学更复杂。 Google为Paraboloid Regression。抛物面天线的曲面具有抛物线的横截面形状,在几何学上称为抛物面。

只有解决了数学问题后,才能开始编程并在列表中查找点。

答案 1 :(得分:0)

事实证明,这个问题实际上可以通过编程解决,无需高级数学。给定y值并要求在非对称/抛物线弧上找到两个相应的x值,您可以简单地将顶点处的弧分成两部分,然后扫描两个阵列中的每一个以获得匹配的x值。它的作用就像一个魅力 - 只需要一点批判性的思考而不是思考它(数学主要的东西:p)