2013-05-27 1 views
0

선의 시작 및 중단 지점을 나타내는 X, Y 값 목록에서 가져온 이미지를 그리려합니다. 그것들은 인치 단위이기 때문에 현재는 소수 자릿수로 형식이 지정되어 있습니다.10 진수 값을 사용하여 캔버스에서 이미지 그리기

내가 가진 문제는 그림과 관련이 있습니다. MoveToLineTo 명령에는 double이 아닌 정수가 필요합니다. Round(float) 수학 연산을 사용하면 아래 출력이 표시됩니다. 반올림은 동일한 시작 및 중단 지점을 가져 오므로 아무 것도 그려지지 않습니다.

십진수 X, Y 점 목록에서 모양을 그리려면 어떻게해야합니까? 입력 값

디버그 코드 (소수)의 출력 점

LineStartVal: -88.988857, 36.265838 
LineEndVal: -89.094923, 36.371904 
LineStartVal: -89.094923, 36.371904 
LineEndVal: -95.000423, 36.371904 
LineStartVal: -95.000423, 36.371904 
LineEndVal: -95.000423, 32.828604 
LineStartVal: -95.000423, 32.828604 
LineEndVal: -99.134273, 32.828604 

코드를 디버깅 찰나 :

MoveTo: -89, 36 
LineTo: -89, 36 
MoveTo: -89, 36 
LineTo: -95, 36 
MoveTo: -95, 36 
LineTo: -95, 33 
MoveTo: -95, 33 
LineTo: -99, 33 

도면 코드 :

//Function used to to get start and stop points 
LSNLineObj.GetEndPoints(X1,Y1,X2,Y2); 


//OutputMemo.Text := OutputMemo.Text + #13#10 + 'LineStartVal: ' + FloatToStrF(X1, ffGeneral, 8, 4) + ', ' + FloatToStrF(Y1, ffGeneral, 8, 4); 
//OutputMemo.Text := OutputMemo.Text + #13#10 + 'LineEndVal: ' + FloatToStrF(X2, ffGeneral, 8, 4) + ', ' + FloatToStrF(Y2, ffGeneral, 8, 4); 

X1int := Round(X1); X2int := Round(X2); 
Y1int := Round(Y1); Y2int := Round(Y2); 

PartImage.Canvas.MoveTo(X1int,X2int); 

OutputMemo.Text := OutputMemo.Text + #13#10 + 'MoveTo: ' + IntToStr(X1int) + ', ' + IntToStr(Y1int); 

PartImage.Canvas.LineTo(X2int,Y2int); 

OutputMemo.Text := OutputMemo.Text + #13#10 + 'LineTo: ' + IntToStr(X2int) + ', ' + IntToStr(Y2int); 
+1

장면/단위의 크기를 조정하십시오. –

+0

0.1 픽셀의 의미는 무엇입니까? –

답변

7

두 좌표계가 있습니다. 첫째, 좌표가 -88.988857, 36.265838 인 '논리'시스템이 있습니다. 둘째, 화면이 있습니다. 이 두 가지 사이를 변환해야합니다. TRealVector 두 개의 복식을 포함하는 기록이 어디 있는지 기능

function LogToScreen(LogPoint: TRealVector): TPoint; 
function ScreenToLog(Point: TPoint): TRealVector; 

를 작성해야합니다. 이 두 함수를 작성하는 것은 초등 학교 수학 만 필요합니다.

예를 들어, 당신은이 화면에 사각형 0..8000..600는 논리 값 -110..-8030..40에 해당 할 수 있습니다.

힌트

: 위와 같이 값을,

function LogToScreen(LogPoint: TRealVector): TPoint; 
begin 
    result.X := round(800 * (LogPoint.X - (-110))/((-80) - (-110))); 
    result.Y := round(600 * (LogPoint.Y - 30)/(40 - 30)); // or rev. orientation 
end; 
0

이 질문에 여러 부분이 있습니다. 1) 세계 좌표를 화면 좌표로 축척하는 법. 2) 형상 데이터를로드하는 방법, 3) 데이터를 그림으로 그리는 방법 .

데이터 변환 정보는 Buro Tshaggelar의 기사 (http://www.ibrtses.com/delphi/dmcs.html)에서 제공됩니다. 그는 데이터 변환을 수행하는 방법에 대해 설명합니다.

Tpaintbox 또는 Timage의 왼쪽 위 모서리의 x, y 좌표는 0입니다. 정수 값이어야합니다. 오프셋 값을 기준으로 배율을 조정하여 세계 좌표를 화면 좌표로 변환하거나 화면 좌표를 세계 좌표로 변환 할 수 있습니다.

도형을 Tpaintbox 또는 TImage Canvas에 플롯 할 수 있습니다. Tpaintbox에 플롯하면 그 결과는 영구적이지 않습니다.

모양을 그리기 위해 개별 선을 그리는 대신 모양을 그리기 위해 Tpoint 배열을 사용하는 것이 좋습니다. 다음은 XE2 VCL에서 작동합니다.

부품

월드 좌표의 좌표는 좌표 xLowvalue, xHighValue 및 yLowVaue 및 yHighValue 함께 상자에 의해 제한되는 십진 값은 1을 화면 창이 tlx..brx으로 정의 될 수 있으며, tly..bry 좌표는 정수 값입니다.

다음 기능은 세계 좌표와 화면 좌표를 변환합니다. Andreas의 전환도 효과가 있습니다. 나는 그것들을 좋아하고 동시에 좌표 쌍을 변환하는 것이 더 효율적입니다. 나는 프로세스를 설명하기 위해 아래의 전환을 선호한다. 세계에서

변환 화면 좌표에 좌표

기능 mapW2SxLin (XF : 더블) : 정수; begin 결과 : = round (tlx + (xf - xlow) * (brx - tlx)/(xhigh - xlow)); 끝;

function mapW2SyLin (yf : double) : 정수; begin 결과 : = round (bry - (yf - ylow) * (bry - tly)/(yhigh - ylow)); 끝;

기능 mapS2WxLin (XS : 정수) : 세계 좌표에 화면에서

변환 좌표 두 번; begin 결과 : = xlow + (xs - tlx) * (xhigh - xlow)/(brx - tlx); 끝;

function mapS2WyLin (ys : 정수) : double; begin 결과 : = yhigh - (ys - tly) * (yhigh - ylow)/(bry - tly); 끝;

ikathygreat가 제공하는 예제에서 원하는 변환은 데카르트 좌표에서 화면 좌표 데이터로 나타납니다 (제공된 값은 십진 위도 및 경도 값으로 표시된 위도 및 경도 위치 쌍인 것 같습니다).

2 부 데이터 파일을로드하는 대신 여기에 하드 코딩됩니다. Goodle for 은 xy 동적 배열을로드하는 예제 인 파일에서 tpoint 배열을 채 웁니다. 텍스트 파일에서 데이터를로드 할 수있는 코드가 있습니다. 데이터를로드 할 때 SetLength (현재 Setlength (xy, 6)로 코딩 됨)의 배열 크기 (6)를 변경하는 코드를 제공하고 배열 크기를 6으로 설정해야합니다. 이렇게하려면 또 다른 질문이 있어야합니다. 값은 모양의 정점 수에 따라 변경됩니다.

제 3

Tpoint 어레이를 사용하여 형상을 플롯. 요청자의 methodlogy를 요청했지만 사용하지 않은 것은 무엇입니까? 개별 선을 그리는 것은 모양을 플롯하기 위해 코드를 작성하는 것이 약간 어색합니다. 나는 아래 예제가 더 간단한 해결책이라고 생각하고 그 일을 끝낸다.

매우 낮음 :

은 사용 좌표 세계의 최대 한계를 반영하는 경계와 상자를 페인트 설정 = -88; // 제공되는 동쪽 위도 x 높이 : = -100; // 주어진 서쪽 경도 yLow : = 37; // 제공된 최고 위도 y 높이 : = 32; // 가장 낮은 위도가

내가 전역 변수를 제안 제공과 같이 정의 할 수 :

VAR 매우 낮음, xHigh, yLow, yHigh : 이중; tlx, brx, tly, bry : 정수;

xy : TPoint의 배열;

배열을 사용하여 형상을 플롯은 당신에게 TPoint 유형의

형 TMyPolygon = 배열을 정의 할 필요가있다; // 동적 배열

하고 한 OnCreate 형태의 이벤트 핸들러에서 이러한 값을 지정 :

BRX : = Paintbox1.Left; tlx : = Paintbox1.Left + paintbox1.Width; bry : = Paintbox1.Top; tly : = Paintbox1.Top + paintbox1.Height;

이미지, 그림판 및 단추를 양식에 추가하십시오. 그런 다음 Button 및 Form OnCreate 핸들러에서 다음 코드를 사용합니다. 또한 변환 함수와 전역 변수 (xLow, xHigh, yLow, yHigh : double; tlx, brx, tly, bry : 정수, xy : Point 배열)를 추가하고 Tpoint 유형을 추가해야합니다. (type TMyPolygon = array of

enter image description here

I가 제공하는 데이터와 결과 모양을보고, 나는 데이터가 나열되어 있지 않을 수도 있습니다 :; TPoint는)

implementation 

{$R *.dfm} 

    function mapW2SxLin(xf:double):integer; 
    begin 
     result:=round(tlx+(xf-xlow)*(brx-tlx)/(xhigh-xlow)); 
    end; 

    function mapW2SyLin(yf:double):integer; 
    begin 
     result:=round(bry-(yf-ylow)*(bry-tly)/(yhigh-ylow)); 
    end; 

    function mapS2WxLin(xs:integer):double; 
    begin 
     result:=xlow+(xs-tlx)*(xhigh-xlow)/(brx-tlx); 
    end; 

    function mapS2WyLin(ys:integer):double; 
    begin 
     result:=yhigh-(ys-tly)*(yhigh-ylow)/(bry-tly); 
    end; 


procedure TPlotShapeFm.Button1Click(Sender: TObject); 
var 
    // xy: array of TPoint; //probably want to define this globally 
    x,y,x1,y1,x2,y2,x3,y3:integer; 
    ax,ay,ax2,ay2:integer; 
begin 

{ Your values 
-88.988857, 36.265838 
-89.094923, 36.371904 
-89.094923, 36.371904 
-95.000423, 36.371904 
-95.000423, 36.371904 
-95.000423, 32.828604 
-95.000423, 32.828604 
-99.134273, 32.828604 
-88.988857, 36.265838 //repeat the first value to close the shape 
} 

//convert from World to screen coordinates 
// these values are hard coded for this example 
// there are many ways to load these from a text file 

    x:= mapW2SxLin(-88.988857); 
    y:= mapW2SyLin(36.265838); 

    ax:= mapW2SxLin(-89.094923); 
    ay:= mapW2SyLin(36.371904); 

    x1:= mapW2SxLin(-95.000423); 
    y1:= mapW2SyLin(36.371904); 

    x2:= mapW2SxLin(-95.000423); 
    y2:= mapW2SyLin(32.828604); 

    ax2:= mapW2SxLin(-99.134273); 
    ay2:= mapW2SyLin(32.828604); 

    x3:= mapW2SxLin(-88.988857); //return to the starting coordinates to finish off the shape 
    y3:= mapW2SyLin(36.265838); 

    // populate the dynamic array 
    Setlength(xy, 6); 
    xy[0] := point(x,y); 
    xy[1] := point(ax,ay); 
    xy[2] := point(x1,y1); 
    xy[3] := point(x2,y2); 
    xy[4] := point(ax2,ay2); 
    xy[5] := point(x3,y3); 

    Paintbox1.Canvas.Brush.Color := Random($FFFFFF); 

    //plot the shape 
    //canvas.Polygon(xy); //generic or plot on the form itself 
    // or 
    Image1.canvas.polygon(xy); //to plot on a Timage 
    Paintbox1.canvas. polygon(xy); //to plot on a Tpaintbox 


end; 

procedure TPlotShapeFm.FormCreate(Sender: TObject); 
begin 

    //You can set up you paint box using: 

{ xLow := 0; 
    xHigh:=-180; 
    yLow:= 50; 
    yHigh:= 30; //to display part of North America or 


    xLow := 180; 
    xHigh:=-180; 
    yLow:= 90; 
    yHigh:= 00; //to display the entire World, North of the equator. 

} 

// but to display the info provided as a large image 
    xLow := -88; 
    xHigh:=-100; 
    yLow:= 37; 
    yHigh:= 32; 

    // scale the paintbox to World coordinates 
    brx:= Paintbox1.Left; 
    tlx:= Paintbox1.Left + paintbox1.Width; 
    bry:= Paintbox1.Top; 
    tly := Paintbox1.Top + paintbox1.Height; 

end; 

그것은 바로, 결과는 같다 수행 요청자가 배열을 사용하여 모양을 올바르게 그려야하는 순서 (크로스 오버에주의). 크로스 오버는 초기 지점에서 시계 방향 또는 반 시계 방향으로 점을 나열한 다음 초기 지점에서 끝내면 해결할 수 있습니다. 초기 지점에서 도면을 완료하여 모양을 닫아야합니다 (MUST).

0

는 "어떻게 진수 X의 목록, Y 점에서 내 모양을 그릴 수?"

http://graphics32.org/

var 
    pts: TArrayOfFixedPoint; 
    fr: TFloatRect; 
begin 
    ... 
    pts := MakeArrayOfFixedPoints(fr); 
    SimpleFill(Bitmap, pts, Color32(clBlack), clCornSilk32); 

사냥을 다음 엑스트라 아래 : GR32_Lines을 GR32_Misc을, GR32_Misc2, GR32_Text. 런타임 패키지에 파일을 추가하십시오. 디자인 타임 패키지는 r/t 패키지에 올바르게 종속되어 있으므로 별도의 단계가 필요하지 않습니다. 나는 최근에 XE5와 XE7을 만들었습니다.

관련 문제