如何获取dm脚本行注释(组件)的起点/终点?

时间:2018-02-22 00:58:56

标签: annotations dm-script

我想用:

Component NewLineAnnotation( Number top, Number left, Number bottom, Number right )

问题是线总是沿着从左上角到右下角的方向运行。

但是,我需要这条线从右下角到左上角。 而且我还需要能够从现有方向获得准确的指示。

命令不是很愚蠢:
Component NewLineAnnotation( Number start_x, Number start_y, Number end_x, Number end_y )

但肯定有办法获得线注释的方向吗?

void ComponentGetRect( Component comp, NumberVariable top, NumberVariable left, NumberVariable bottom, NumberVariable right )

没有这样的细节。

2 个答案:

答案 0 :(得分:1)

鉴于之前很好的回答中的细节,我看起来更多,并发现这是情况 - 我正在使用GMS 3.

通过以下方式将行创建为组件的命令:

NewLineAnnotation( Number top, Number left, Number bottom, Number right )

可以更好地描述为:

NewLineAnnotation( Number sX, Number sY, Number eX, Number eY )

但另一个潜在混淆的来源。在查找坐标的Get()命令时,会列出以下命令:

void ComponentGetBoundingRect( Component comp, NumberVariable t, NumberVariable l, NumberVariable b, NumberVariable r )

void ComponentGetRect( Component comp, NumberVariable top, NumberVariable left, NumberVariable bottom, NumberVariable right ) 

void ComponentGetRectInView( Component comp, NumberVariable top, NumberVariable left, NumberVariable bottom, NumberVariable right )

所有3个命令都声明顺序:top,left,bottom,right,但只有第一个和最后一个命令。

可以再次更好地描述第二个命令
ComponentGetRect(Number sX, Number sY, Number eX, Number eY)

我将命令NewLineAnnotation()与ComponentGetBoundingRect()混淆了,这引起了一些实际问题。我觉得手册中更好的描述可能有助于避免此类问题。

总结一下,这里有一些代码,用来向我展示不同的功能。

image front := CreateFloatImage("", 800, 800)
front.setZoom(.4)
front.ShowImage()
component frontComponent = front.ImageGetImageDisplay(0)

component solid_Line_orange = NewLineAnnotation(700, 10, 500, 200);
frontComponent.ComponentAddChildAtEnd(solid_Line_orange)
solid_Line_orange.ComponentSetForegroundColor(1,.66,0);
component solid_Line_white  = NewLineAnnotation(500, 10, 700, 200);
frontComponent.ComponentAddChildAtEnd(solid_Line_white)

number sx, sy, ex, ey
number l_top, l_left, l_buttom, l_right
solid_Line_orange.ComponentGetRect( l_top, l_left, l_buttom, l_right );

Result("\n\n")
Result("using:  ComponentGetRectangle();\t actual convention: (start_x, start_y, end_x, end_y)\n")
Result("orange line set at: \t(700, 10, 500, 200);\n")
Result("orange line found at: \t(" + l_top + ", " +  l_left + ", " + l_buttom + ", " + l_right + ")\n")
solid_Line_white.ComponentGetRect( l_top, l_left, l_buttom, l_right ) 
Result("white line set at: \t(500, 10, 700, 200); \n")
Result("white line found at: \t(" + l_top + ", " +  l_left + ", " + l_buttom + ", " + l_right + ")\n")

Result("using:  ComponentGetBoundingRectangle();\t actual convention: (top, left, bottom, right)\n")
solid_Line_orange.ComponentGetBoundingRect( l_top, l_left, l_buttom, l_right ); 
Result("orange line found at: \t(" + l_top + ", " +  l_left + ", " + l_buttom + ", " + l_right + ")\n")
solid_Line_white.ComponentGetBoundingRect( l_top, l_left, l_buttom, l_right ); 
Result("white line found at: \t(" + l_top + ", " +  l_left + ", " + l_buttom + ", " + l_right + ")\n")

Result("using:  ComponentGetBoundingRectInView();\t actual convention: (top, left, bottom, right)\n")
solid_Line_orange.ComponentGetBoundingRectInView( l_top, l_left, l_buttom, l_right ); 
Result("orange line found at: \t(" + l_top + ", " +  l_left + ", " + l_buttom + ", " + l_right + ")\n")
solid_Line_white.ComponentGetBoundingRectInView( l_top, l_left, l_buttom, l_right ); 
Result("white line found at: \t(" + l_top + ", " +  l_left + ", " + l_buttom + ", " + l_right + ")\n")

这解决了我的问题。希望这也有助于其他人。也许手册中更好的描述也有帮助。

答案 1 :(得分:0)

这是一个有趣的问题! 我认为ComponentGetRect()的行为是正确的,但错误标记了文档中的变量名称。虽然它表示它返回一个矩形作为左上角到右下角坐标,它实际上返回Y / X起始坐标和Annotation的Y / X结束坐标对。 (对于其他类型的annoations,这就是[TLBR])。注意它是Y / X而不是X / Y!这是令人困惑的,但要保持与更一般的"组件"对象

同样,NewLineAnnotation()的签名变量名称是错误的,因为它们是一个开始结束方向的obvisoulsy,因为您可以在使用箭头注释时轻松尝试。 (参见下面的示例脚本。)

  

您可以使用以下方法defenitly设置创建的线条或箭头注释的方向:

  Component NewLineAnnotation( Number StartY, Number StartX, Number EndY, Number EndX )
  Component NewArrowAnnotation( Number StartY, Number StartX, Number EndY, Number EndX )

  同样,你应该用来阅读这些位置:
  ComponentGetRect( NumberVariable StartY, NumberVariable StartX, NumberVariable EndY, NumberVariable EndX )

现在,获取开始和结束坐标的另一种方法是组件的控制点,F1帮助文档明确列出控制点ID值: enter image description here

因此,可能正确的方法是使用以下方法向组件询问指定的控制点的坐标:

Boolean ComponentGetControlPoint( Component comp, Number loc, NumberVariable x, NumberVariable y )

但是,对此进行测试(请参阅下面的脚本),它实际上不适用于控制点 ID值12。似乎没有用命令实现一行的开始/结束的两个控制点。

但是,你可以使用" Top / Left" 控制点 4用于获取起始值和" Bottom / Right" 控制点 7用于获取结束值。同样,这只是匹配" line / arrow"的相同的不规则映射。关于常规组件的注释。

  

获取起点XY的另一种方式:
  Boolean ComponentGetControlPoint( Component comp, 4, NumberVariable x, NumberVariable y )

  获得终点XY的另一种方式:
  Boolean ComponentGetControlPoint( Component comp, 7, NumberVariable x, NumberVariable y )

使用的测试脚本

// Control Point constants. See F1 help documentaton ("Component Object" Overview)
number kLineStart   = 1 // = start point of line
number kLineEnd     = 2 // = end point of line
number kTopLeft     = 4 // = top-left for rect, or start point for line
number kBottomRight = 7 // = bottom-right for rect, or end point for line

number sx = 50
number sy = 30
number ex = 400
number ey = 200
number sizeX = 500
number sizeY = 500

void PrintAnnoInfo( component anno )
{
    if ( !anno.ComponentIsValid() ) return
    number t,l,b,r
    anno.ComponentGetRect( t, l, b, r ) 
    // note that it is return StartY, StartX, EndY, EndX into TLBR!

    number type = anno.ComponentGetType()
    Result( "\n\n Component of type " + type + ":" )
    Result( "\n\t Position rect: " + t + " / " + l + " / "+ b + " / "+ r )
    Result( "\n\t\t { TOP / LEFT / BOTTOM / RIGHT }" )

    number sx, sy, ex, ey
    if ( !anno.ComponentGetControlPoint( kLineStart, sx, sy ) )
        Result( "\n INVALID Control point for annotation type. ( " + kLineStart + " ) " )
    else
        Result( "\n\t Start point (X/Y): " + sx + " / " + sy )
    if ( !anno.ComponentGetControlPoint( kLineEnd, ex, ey ) )
        Result( "\n INVALID Control point for annotation type. ( " + kLineEnd + " ) " )
    else
        Result( "\n\t End point (X/Y)  : " + ex + " / " + ey )

    if ( !anno.ComponentGetControlPoint( kTopLeft, sx, sy ) )
        Result( "\n INVALID Control point for annotation type. ( " + kLineStart + " ) " )
    else
        Result( "\n\t Start point (X/Y): " + sx + " / " + sy )
    if ( !anno.ComponentGetControlPoint( kBottomRight, ex, ey ) )
        Result( "\n INVALID Control point for annotation type. ( " + kLineEnd + " ) " )
    else
        Result( "\n\t End point (X/Y)  : " + ex + " / " + ey )

Result( "\n\n" )

}

// clear workspace and created dummy
EGUPerformActionWithAllShownImages( "Delete" )
ClearResults()
Result( "Component direction test:\n\n" )
image img := Realimage( "Test", 4, sizeX, sizeY )
img.ShowImage()
imageDisplay disp = img.ImageGetImageDisplay(0)

// Creating and adding line-Annotation
number UseArrow
useArrow = TwoButtonDialog( "In this test use", "Arrows", "Lines" )
string msg
msg = "\nAdding " + (useArrow?"arrow":"line") + ":"
msg += "\n from (" + sx + " / " + sy + ") to (" + ex + " / " + ey + ")"
msg += "\n { from (Ex/Ey) to (Sx/Sy) }"
Result( msg )
OKdialog( msg )

Component anno
if ( useArrow )
    anno = NewArrowAnnotation( sy, sx, ey, ex ) // note that it is YX!
else
    anno = NewLineAnnotation( sy, sx, ey, ex )  // note that it is YX!

anno.ComponentSetForegroundcolor(1,0,0)
disp.ComponentAddChildAtEnd( anno )
anno.PrintAnnoInfo()

msg = "\nAdding " + (useArrow?"arrow":"line") + ":"
msg += "\n from (" + ex + " / " + ey + ") to (" + sx + " / " + sy + ")"
msg += "\n { from (Ex/Ey) to (Sx/Sy) }"
Result( msg )
OKdialog( msg )

if ( useArrow )
    anno = NewArrowAnnotation( ey, ex, sy, sx ) // note that it is YX!
else
    anno = NewLineAnnotation( ey, ex, sy, sx )  // note that it is YX!


anno.ComponentSetForegroundcolor(0,1,0)
disp.ComponentAddChildAtBeginning( anno )
anno.PrintAnnoInfo()