hexagon logo

The shortest way to the center(scan)

When scanned in the shape shown in the figure

I want to know how to find the shortest distance between each point relative to the center.

There will be more than 140 such bends, so the we should be able to find them automatically.




For reference, the program version : PCDMIS 2019 R2 CAD++







  • I never user the program CurveAnalyzer. Maybe it could make the measurement/automation easier but you would need to ask Hexagon about this.
    In my opinion you could do the measurement directly in PC-DMIS. Either with a modified script or with a solution like proposed.
    Another attempt could be to use neil.challinor solution inside a loop.
  • Sorry to double post.. but I just found the website to CurveAnalyzer: https://ams3d.astrei.com/CA/downloads.htm

    The features shown in the promo video "CurveAnalyzer_Intro_2021-10(KR).mp4" look amazing.

    neil.challinor
    Do you know if this is still being developed? And is this something that could be integrated into PC-DMIS as a module?
  • An update...
    My previous solution gives the closest hit to a theo angle, but this hit could be different than the min radius of this tooth.
    You can add some assignments to find around this hit the min radius (In the code, I take 3 hits on each side of the closest hit - in V6)
    Hope this help :
    SCN1 =FEAT/SCAN,FREEFORM,NUMBER OF HITS=8261,SHOW HITS=NO,SHOWALLPARAMS=NO
    MEAS/SCAN
    BASICSCAN/FREEFORM,NUMBER OF HITS=8261,SHOW HITS=NO,SHOWALLPARAMS=NO
    ENDSCAN
    ENDMEAS/
    CIR1 =FEAT/CIRCLE,CARTESIAN,IN,MAX_INSC,NO
    THEO/<-0.0011,0.0001,0>,<0,0,1>,37.9887
    ACTL/<-0.0011,0.0001,0>,<0,0,1>,37.9887
    CONSTR/CIRCLE,BF,3D,SCN1,,
    OUTLIER_REMOVAL/OFF,3
    FILTER/OFF,UPR=0
    C1 =COMMENT/INPUT,NO,FULL SCREEN=NO,
    Enter number of tooth
    ASSIGN/V1=360/C1.INPUT
    ASSIGN/V2=SQRT(DOT(SCN1.HIT[1..SCN1.NUMHITS].XYZ-CIR1.XYZ,SCN1.HIT[1..SCN1.NUMHITS].XYZ-CIR1.XYZ))
    ASSIGN/V3=SCN1.HIT[MININDEX(V2)].XYZ
    F1 =GENERIC/POINT,DEPENDENT,CARTESIAN,$
    NOM/XYZ,<V3.X,V3.Y,V3.Z>,$
    MEAS/XYZ,<V3.X,V3.Y,V3.Z>,$
    NOM/IJK,<0,0,1>,$
    MEAS/IJK,<0,0,1>
    A1 =ALIGNMENT/START,RECALL:STARTUP,LIST=YES
    ALIGNMENT/LEVEL,ZPLUS,PLN1
    ALIGNMENT/ROTATE_CIRCLE,XPLUS,TO,CIR1,AND,F1,ABOUT,ZPLUS
    ALIGNMENT/TRANS,ZAXIS,PLN1
    ALIGNMENT/TRANS,XAXIS,CIR1
    ALIGNMENT/TRANS,YAXIS,CIR1
    ALIGNMENT/END
    ASSIGN/ANG_HIT=RAD2DEG(ATAN(SCN1.HIT[1..SCN1.NUMHITS].Y/SCN1.HIT[1..SCN1.NUMHITS].X))
    ASSIGN/COR_HIT=((SCN1.HIT[1..SCN1.NUMHITS].X-ABS(SCN1.HIT[1..SCN1.NUMHITS].X))/(SCN1.HIT[1..SCN1.NUMHITS].X-ABS(SCN1.HIT[1..SCN1.NUMHITS].X)))*180
    ASSIGN/ANG_COR=ANG_HIT+COR_HIT
    V4 =LOOP/START,ID=YES,NUMBER=C1.INPUT,START=1,SKIP=,
    OFFSET:XAXIS=0,YAXIS=0,ZAXIS=0,ANGLE=0
    ASSIGN/ANG1=V1*(V4-1)
    ASSIGN/V5=MININDICES(ABS(ANG_COR-ANG1))
    ASSIGN/V6=ARRAY(V2[V5[1]],V2[V5[2]],V2[V5[3]],V2[V5[4]],V2[V5[5]],V2[V5[6],V2[V5[7]])
    ASSIGN/V7=MININDEX(V6)
    ASSIGN/V8=SCN1.HIT[V5[V7]].XYZ
    F2 =GENERIC/POINT,DEPENDENT,CARTESIAN,$
    NOM/XYZ,<V8.X,V8.Y,V8.Z>,$
    MEAS/XYZ,<V8.X,V8.Y,V8.Z>,$
    NOM/IJK,<0,0,1>,$
    MEAS/IJK,<0,0,1>
    LOOP/END
    ASSIGN/V9="F2[1.."+C1.INPUT+"]"
    CIR2 =FEAT/CIRCLE,CARTESIAN,IN,LEAST_SQR,NO
    THEO/<0.0498,-0.1209,0>,<0,0,1>,38.142
    ACTL/<0.0498,-0.1209,0>,<0,0,1>,38.142
    CONSTR/CIRCLE,BF,2D,V9,,
    OUTLIER_REMOVAL/OFF,3
    FILTER/OFF,UPR=0


    To do it, you need to type in the edit window...
    At the start, it seems to be difficult, but it becomes quickly very simple !
    Good luck !​
  • New update because of (bad) using of ATAN...Disappointed
    SCN1 =FEAT/SCAN,FREEFORM,NUMBER OF HITS=8261,SHOW HITS=NO,SHOWALLPARAMS=NO
    MEAS/SCAN
    BASICSCAN/FREEFORM,NUMBER OF HITS=8261,SHOW HITS=NO,SHOWALLPARAMS=NO
    ENDSCAN
    ENDMEAS/
    CIR1 =FEAT/CIRCLE,CARTESIAN,IN,MAX_INSC,NO
    THEO/<0,-0.0005,0>,<0,0,1>,77.9904
    ACTL/<0,-0.0005,0>,<0,0,1>,77.9904
    CONSTR/CIRCLE,BF,3D,SCN1,,
    OUTLIER_REMOVAL/OFF,3
    FILTER/OFF,UPR=0
    C1 =COMMENT/INPUT,NO,FULL SCREEN=NO,
    Enter number of tooth
    ASSIGN/V1=360/C1.INPUT
    ASSIGN/V2=SQRT(DOT(SCN1.HIT[1..SCN1.NUMHITS].XYZ-CIR1.XYZ,SCN1.HIT[1..SCN1.NUMHITS].XYZ-CIR1.XYZ))
    ASSIGN/V3=SCN1.HIT[MININDEX(V2)].XYZ
    F1 =GENERIC/POINT,DEPENDENT,CARTESIAN,$
    NOM/XYZ,<V3.X,V3.Y,V3.Z>,$
    MEAS/XYZ,<V3.X,V3.Y,V3.Z>,$
    NOM/IJK,<0,0,1>,$
    MEAS/IJK,<0,0,1>
    A1 =ALIGNMENT/START,RECALL:STARTUP,LIST=YES
    ALIGNMENT/LEVEL,ZPLUS,PLN1
    ALIGNMENT/ROTATE_CIRCLE,XPLUS,TO,CIR1,AND,F1,ABOUT,ZPLUS
    ALIGNMENT/TRANS,ZAXIS,PLN1
    ALIGNMENT/TRANS,XAXIS,CIR1
    ALIGNMENT/TRANS,YAXIS,CIR1
    ALIGNMENT/END
    ASSIGN/ANG_HIT=RAD2DEG(ATAN(SCN1.HIT[1..SCN1.NUMHITS].Y/SCN1.HIT[1..SCN1.NUMHITS].X))
    ASSIGN/COR_HIT1=((SCN1.HIT[1..SCN1.NUMHITS].X-ABS(SCN1.HIT[1..SCN1.NUMHITS].X))/(SCN1.HIT[1..SCN1.NUMHITS].X-ABS(SCN1.HIT[1..SCN1.NUMHITS].X)))
    ASSIGN/COR_HIT2=((SCN1.HIT[1..SCN1.NUMHITS].Y-ABS(SCN1.HIT[1..SCN1.NUMHITS].Y))/(SCN1.HIT[1..SCN1.NUMHITS].Y-ABS(SCN1.HIT[1..SCN1.NUMHITS].Y)))
    ASSIGN/ANG_COR=ANG_HIT+180*(COR_HIT1)+360*(COR_HIT2*(1-COR_HIT1))
    V4 =LOOP/START,ID=YES,NUMBER=C1.INPUT,START=1,SKIP=,
    OFFSET:XAXIS=0,YAXIS=0,ZAXIS=0,ANGLE=0
    ASSIGN/ANG1=V1*(V4-1)
    ASSIGN/V5=MININDICES(ABS(ANG_COR-ANG1))
    ASSIGN/V6=ARRAY(V2[V5[1]],V2[V5[2]],V2[V5[3]],V2[V5[4]],V2[V5[5]],V2[V5[6]])
    ASSIGN/V7=MININDEX(V6)
    ASSIGN/V8=SCN1.HIT[V5[V7]].XYZ
    F2 =GENERIC/POINT,DEPENDENT,CARTESIAN,$
    NOM/XYZ,<V8.X,V8.Y,V8.Z>,$
    MEAS/XYZ,<V8.X,V8.Y,V8.Z>,$
    NOM/IJK,<0,0,1>,$
    MEAS/IJK,<0,0,1>
    LOOP/END
    ASSIGN/V9="F2[1.."+C1.INPUT+"]"
    CIR2 =FEAT/CIRCLE,CARTESIAN,IN,LEAST_SQR,NO
    THEO/<0.0001,0.0004,0>,<0,0,1>,78.0006
    ACTL/<0.0001,0.0004,0>,<0,0,1>,78.0006
    CONSTR/CIRCLE,BF,2D,V9,,
    OUTLIER_REMOVAL/OFF,3
    FILTER/OFF,UPR=0