hexagon logo

How to declare an array in DMIS

I want to write a code to calculate the circle center of three points and radius among dozens points in order to find the radius which is closest to my target radius. First I have to assign the points' x, y, z into an array then calculate them by do loop. I followed the page's array code however it seems not the case :
https://docs.hexagonmi.com/pcdmis/2019.1/en/helpcenter/mergedProjects/core/26_expression_topics/Variable_Arrays.htm
  • Hi,

    there are a couple of tools that take this away from you, e.g. fit the radius into the curve, etc.

    how are the points? a scan?
    post the code you already created, the help page is correct, the error must be somewhere else​
  • Assigning hits in an array works like this :
    ASSIGN/V1=CIRC1.HIT[1..CIRC1.NUMHITS].XYZ

    If you're looking for a special radius, you have to calculate all the radii :
    ASSIGN/V2=SQRT(DOT(V1-CIRC1.XYZ,V1-CIRC1.XYZ))

    The three hits closest to the target value are :
    ASSIGN/V3=CIRC1.TR....................................... ..(theo radius of CIRC1 : your target value ?)
    ASSIGN/V4=ABS(V2-V3)......................................positive difference between all radii and target
    ASSIGN/V5=MININDICES(V4).............................sorting radii indices
    ASSIGN/V6="CIRC1.HIT["+V5[1]+"]"
    ASSIGN/V7="CIRC1.HIT["+V5[2]+"]"
    ASSIGN/V8="CIRC1.HIT["+V5[3]+"]"
    F1 =GENERIC/POINT,DEPENDENT,CARTESIAN,$
    NOM/XYZ,<V6.X,V6.Y,V6.Z>,$
    MEAS/XYZ,<V6.X,V6.Y,V6.Z>,$
    NOM/IJK,<V6.I,V6.J,V6.K>,$
    MEAS/IJK,<V6.I,V6.J,V6.K>
    F2 =GENERIC/POINT,DEPENDENT,CARTESIAN,$
    NOM/XYZ,<V7.X,V7.Y,V7.Z>,$
    MEAS/XYZ,<V7.X,V7.Y,V7.Z>,$
    NOM/IJK,<V7.I,V7.J,V7.K>,$
    MEAS/IJK,<V7.I,V7.J,V7.K>​
    ​​​​​​​F3 =GENERIC/POINT,DEPENDENT,CARTESIAN,$
    NOM/XYZ,<V8.X,V8.Y,V8.Z>,$
    MEAS/XYZ,<V8.X,V8.Y,V8.Z>,$
    NOM/IJK,<V8.I,V8.J,V8.K>,$
    MEAS/IJK,<V8.I,V8.J,V8.K>


    Then construct the circle with F1,F2,F3.​​
  • I think I found out how to declare an array at DMIS. Just put square brackets at the end of the declaration such as DECL/COMMON,REAL,POINTS[8,15]. Then the array can be assigned number into its slots like POINTS[1,3] = ASSIGN/1.325 .
  • Thanks your code. It's a little advanced to me but it's supposed to be helpful for me to improve my DMIS understanding.
    I found out how to declare array on DMIS : DECL/COMMON,REAL,POINTS[8,15].
    I have written some codes on C# to achieve my purpose but I hope it also can be realized on DMIS as well so I can directly adopt the DMIS features instead of spending time on copying many numbers to another program.
    This is my C# code to calculate the circle center for the purpose I post on top :


    using System;
    using System.Diagnostics;
    using System.Globalization;
    using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
    using System.Windows.Forms;
    using System.IO;

    namespace WinFormsApp1
    {
    public partial class Form1 : Form
    {
    int pointCounts;
    int[] pointPositions = new int[3];



    public Form1()
    {
    InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
    calculate();
    }

    private void calculate()
    {


    string str;
    char ch = ';';
    char dot = ',';

    str = textBox1.Text;
    string[] sArray = str.Split(new char[2] { ';', ',' });
    int chfreq = str.Count(f => (f == ch));
    int dotfreq = str.Count(f => (f == dot));
    float[,] coordinations = new float[90, 3];


    for (int i = 0; i < sArray.Count(); i++)
    {
    Trace.WriteLine(sArray );
    }


    if (sArray.Count() % 3 == 0 && textBox2.Text != null)
    {
    pointCounts = sArray.Count() / 3;
    for (int i = 0; i < (sArray.Count() + 1) / 3; i++)
    {
    for (int j = 0; j <= 2; j++)
    {
    coordinations[i, j] = float.Parse(sArray[i * 3 + j], CultureInfo.InvariantCulture.NumberFormat);
    //Trace.WriteLine("arrary count " + sArray.Count() + "array number : " + coordinations[i,j] + " i value : " + i + " j value : " + j);
    }
    }
    radious(coordinations);
    }
    else
    {
    var result = MessageBox.Show("error", "error",
    MessageBoxButtons.YesNo,
    MessageBoxIcon.Question);
    }



    //label1.Text = chfreq.ToString() + " " + dotfreq.ToString();
    }

    private void radious(float[,] inputArray)
    {
    double radiusGap = 100000f;
    float[] currentCircleCenter = new float[3];
    double currentRadius;
    float targetRadius = float.Parse(textBox2.Text);
    double bestRadius = 0;
    string textString = "";

    foreach (float a in inputArray)

    {
    if (a != null) { }
    //Trace.WriteLine(inputArray.Length);


    }

    for (int i = 0; i <= pointCounts - 2 - 1; i++)
    {
    for (int j = i + 1; j <= pointCounts - 1 - 1; j++)
    {
    for (int k = j + 1; k <= pointCounts - 1; k++)
    {


    float a1, a2, a3, b1, b2, b3, c1, c2, c3, d1, d2, d3, factor0, factor1, factor2, factor3;
    a1 = inputArray[i, 0] - inputArray[j, 0]; a2 = inputArray[i, 1] - inputArray[j, 1]; a3 = inputArray[i, 2] - inputArray[j, 2];
    b1 = inputArray[j, 0] - inputArray[k, 0]; b2 = inputArray[j, 1] - inputArray[k, 1]; b3 = inputArray[j, 2] - inputArray[k, 2];
    c1 = (inputArray[j, 1] - inputArray[i, 1]) * (inputArray[k, 2] - inputArray[i, 2]) - (inputArray[j, 2] - inputArray[i, 2]) * (inputArray[k, 1] - inputArray[i, 1]);
    c2 = (inputArray[j, 2] - inputArray[i, 2]) * (inputArray[k, 0] - inputArray[i, 0]) - (inputArray[j, 0] - inputArray[i, 0]) * (inputArray[k, 2] - inputArray[i, 2]);
    c3 = (inputArray[j, 0] - inputArray[i, 0]) * (inputArray[k, 1] - inputArray[i, 1]) - (inputArray[j, 1] - inputArray[i, 1]) * (inputArray[k, 0] - inputArray[i, 0]);
    d1 = (inputArray[i, 0] * inputArray[i, 0] - inputArray[j, 0] * inputArray[j, 0] + inputArray[i, 1] * inputArray[i, 1] - inputArray[j, 1] * inputArray[j, 1] + inputArray[i, 2] * inputArray[i, 2] - inputArray[j, 2] * inputArray[j, 2]) / 2;
    d2 = (inputArray[j, 0] * inputArray[j, 0] - inputArray[k, 0] * inputArray[k, 0] + inputArray[j, 1] * inputArray[j, 1] - inputArray[k, 1] * inputArray[k, 1] + inputArray[j, 2] * inputArray[j, 2] - inputArray[k, 2] * inputArray[k, 2]) / 2;
    d3 = c1 * inputArray[i, 0] + c2 * inputArray[i, 1] + c3 * inputArray[i, 2];

    factor0 = a1 * b2 * c3 + b1 * c2 * a3 + c1 * a2 * b3 - c1 * b2 * a3 - b1 * a2 * c3 - a1 * c2 * b3;
    factor1 = d1 * b2 * c3 + d2 * c2 * a3 + d3 * a2 * b3 - d3 * b2 * a3 - d2 * a2 * c3 - d1 * c2 * b3;
    factor2 = a1 * d2 * c3 + b1 * d3 * a3 + c1 * d1 * b3 - c1 * d2 * a3 - b1 * d1 * c3 - a1 * d3 * b3;
    factor3 = a1 * b2 * d3 + b1 * c2 * d1 + c1 * a2 * d2 - c1 * b2 * d1 - b1 * a2 * d3 - a1 * c2 * d2;

    currentCircleCenter[0] = factor1 / factor0; currentCircleCenter[1] = factor2 / factor0; currentCircleCenter[2] = factor3 / factor0;

    currentRadius = Math.Pow(Math.Pow(inputArray[i, 0] - currentCircleCenter[0], 2) + Math.Pow(inputArray[i, 1] - currentCircleCenter[1], 2) + Math.Pow(inputArray[i, 2] - currentCircleCenter[2], 2), 0.5);

    textString = textString + " _points : " + (i + 1).ToString() + " , " + (j + 1).ToString() + " , " + (k + 1).ToString() +
    " _radius : " + currentRadius.ToString() + " \r\n\r\n ";


    if (Math.Abs(currentRadius - targetRadius) < radiusGap)
    {
    radiusGap = Math.Abs(currentRadius - targetRadius);
    bestRadius = currentRadius;
    pointPositions[0] = i + 1; pointPositions[1] = j + 1; pointPositions[2] = k + 1;
    Trace.WriteLine("radius : " + currentRadius + " points positions : " + i.ToString() + j.ToString() + k.ToString());


    }

    textBox3.Text = "radius : " + bestRadius + " , best points : " + pointPositions[0].ToString() + " , " + pointPositions[1].ToString() + " , " + pointPositions[2].ToString() + " \r\n \r\n " + textString;
    }
    }


    }

    }

    private void textBox2_TextChanged(object sender, EventArgs e)
    {

    }



    //Console.WriteLine(item);

    }
    }
  • Hello,

    with modifications, your code can be implemented as an external program that pulls the data from the open pcDMIS measurement routine.

    or you write a basic script.

    I wouldn't recommend doing this directly in pcdmis, the options are too limited for that and loops take far too long​
  • : this is not "code", this can be written directly in the edit window, or using insert/assignment.
    The toolbox of PC-DMIS is a great tool, I prefer using it as adding external scripts.
  • I feel the same way if I can pull the data from DMIS to the program more plastic. Thanks for the suggestion.