การปรับสเกลหน้าจอแบบพอดีกับกราฟิกคาน
สรกานต์ ศรีตองอ่อน
ความนำ
ปัญหาต่อมาในการแสดงกราฟิกคานกรณีเรากำหนดสเกลในการแสดงผลที่หน้าจอแบบคงที่คือเมื่อคานนั้นมีความยาวรวมมากกว่าสเกลที่ตั้งไว้ก็จะทำให้แสดงได้ไม่เต็มภาพวิธีแก้มี 2 แบบ คือ
1. ปรับสเกลแบบ Best Fitคือพอดีกับภาพที่แสดงเสมอ
2.ใช้วิธีเลื่อนจอภาพได้
บทความนี้จะแสดงวิธีที่1โดยกรณีของกราฟิกคานความยาวจะแปรเปลี่ยนเฉพาะแนวแกนX เท่านั้น ส่วนแกน Yจะใช้หลักการ 3/4 เท่าของแกน X
แนวคิด
เราใช้วิธีกำหนดสเกลหน้าจอแบบยืดหยุ่นคือ
ตรวจสอบความยาวของภาพที่จะแสดงก่อน แล้วปรับสเกลแกน X ทีหลัง
พิกัดขอบซ้ายให้เริ่มที่ -2 m เสมอ เพราะเริ่มพล็อตภาพที่พิกัด 0 นั่นคือเว้นระยะห่างออกไปทางซ้ายจากภาพ 2 m
พิกัดขอบขวาจะเท่ากับความยาวรวมของคาน+2 m นั่นคือเว้นระยะห่างออกไปทางขวาจากภาพ 2 m
สเกลแกน Y เท่ากับ 3/4 เท่าของสเกลแกน X โดยพิกัดขอบล่างเริ่มที่ -2 m
ดังนั้น พิกัดขอบบนเท่ากับ (3 * ความยาวสเกลแกน X \\ 4) - 2
การโปรแกรม
1.ปรับโค้ดของโปรแกรมเดิมตามรายละเอียดด้านล่างโดยมี Subเพิ่มเติมซึ่งเป็นจุดสำคัญคือFitScreen
---------------------------------------------------------------------------------------------------
Option Explicit
Dim Xmin As Single: Dim Xmax As Single
Dim Ymin As Single: Dim Ymax As Single
Dim StepX As Single: Dim StepY As Single
Const N = 3 \'สมมุติจำนวนช่วงคานเท่ากับ 3
Dim L(0 To N + 1) As Single \'ความยาวแต่ละช่วงคาน
Dim SumL As Single \'ผลรวมความยาวของแต่ละช่วงคาน
\' รูปแบบคาน : 1 = ไม่มีช่วงยื่น, 2 =ปลายยื่นซ้าย
\' 3 = ปลายยื่นขวา, 4 =ปลายยื่นสองด้าน
Dim BeamType As Integer
Dim S As Integer \' ค่าเริ่มต้นของลูป
Dim E As Integer \' ค่าจบของลูป
----------------------------------------------------------------------------------------------------
Sub PlotBeam()
Dim I As Integer
Dim X As Single: Dim Y As Single
Dim d As String
\' สร้างกราฟิกคานแต่ละช่วง
X = 0: Y = Ymax - 5
For I = S To E
Line (X, Y + 0.1)-(X + L(I), Y), QBColor(1), B
X = X + L(I)
Next I
\' เส้นบอกความยาวแต่ละช่วง
X = 0: Y = Ymax - 7
Line (X, Y)-(X + SumL, Y), QBColor(4)
Line (X, Y + 0.5)-(X, Y - 0.5), QBColor(4)
For I = S To E
X = X + L(I)
Line (X, Y + 0.5)-(X, Y - 0.5), QBColor(4)
Next I
\' แสดงค่าความยาวแต่ละช่วง
X = 0: Y = Ymax - 7
For I = S To E
d = Format(L(I), "0.00")
CurrentX = X + (L(I) / 2) - (TextWidth(d) / 2)
CurrentY = Y - TextHeight(d)
Print d
X = X + L(I)
Next I
\' เส้นแรงปฏิกิริยา
X = 0: Y = Ymax - 5
Select Case BeamType
Case 2, 4 \' ปลายยื่นซ้าย,ปลายยื่นสองด้าน
X = X + L(0)
End Select
DrawWidth = 3
Line (X, Y)-(X, Y - 1), QBColor(1)
Line (X, Y)-(X - 0.1, Y - 0.1), QBColor(1)
Line (X, Y)-(X + 0.1, Y - 0.1), QBColor(1)
DrawWidth = 1
For I = 1 To N
X = X + L(I)
DrawWidth = 3
Line (X, Y)-(X, Y - 1), QBColor(1)
Line (X, Y)-(X - 0.1, Y - 0.1), QBColor(1)
Line (X, Y)-(X + 0.1, Y - 0.1), QBColor(1)
DrawWidth = 1
Next I
End Sub
----------------------------------------------------------------------------------------------------
Private Sub Form_Activate()
Dim Row As Integer: Dim Col As Integer
Dim NumX As Single: Dim NumY As Single
Dim X As Single: Dim Y As Single
Me.Scale (Xmin, Ymax)-(Xmax, Ymin) \'กำหนดสเกลการแสดงผล
NumX = (Abs(Xmax - Xmin) / StepX) + 1 \' หาจำนวนจุดกริดในแกนX
NumY = (Abs(Ymax - Ymin) / StepY) + 1 \' หาจำนวนจุดกริดในแกนY
Cls \' เคลียร์หน้าจอ
\' พล็อตจุดกริด
X = Xmin: Y = Ymin
For Row = 1 To NumX
For Col = 1 To NumY
PSet (X, Y), QBColor(4)
Y = Y + StepY
Next Col
X = X + StepX: Y = Ymin
Next Row
\' ลากเส้นแกนอ้างอิงพิกัด (0,0)
Line (0, 0)-(1.5, 0), QBColor(4): Line (0, 0)-(0, 1.5), QBColor(4)
\'เรียกโปรแกรมย่อยสำหรับสร้างกราฟิกคาน
PlotBeam
End Sub
----------------------------------------------------------------------------------------------------
Sub FitScreen()
Dim I As Integer
\' หาค่าเริ่มต้นและค่าจบของลูป
Select Case BeamType
Case 1 \' ไม่มีช่วงยื่น
S = 1: E = N
Case 2 \' ปลายยื่นซ้าย
S = 0: E = N
Case 3 \' ปลายยื่นขวา
S = 1: E = N + 1
Case 4 \' ปลายยื่นสองด้าน
S = 0: E = N + 1
End Select
\'หาผลรวมความยาวของแต่ละช่วงคาน
SumL = 0
For I = S To E
SumL = SumL + L(I)
Next I
\' กำหนดสเกลหน้าจอแกน X เซ็ตขอบซ้ายที่-2 m เสมอ
Xmin = -2: Xmax = SumL + 2
\' กำหนดสเกลหน้าจอแกน Y เท่ากับ3/4 เท่าของแกน X โดยเซ็ตขอบล่างที่-2 m เสมอ
Ymin = -2: Ymax = (3 * (Xmax + Abs(Xmin)) \\ 4) - Abs(Ymin)
End Sub
----------------------------------------------------------------------------------------------------
Private Sub Form_Load()
Dim I As Integer
Me.WindowState = 2 \'ขยายฟอร์มให้เต็มจอภาพ
Me.ScaleMode = 0 \' กำหนดสเกลหน้าจอเอง
Me.BackColor = vbWhite \' สีฉากหลังเป็นสีขาว
Me.AutoRedraw = True \'จัดเก็บการแสดงผลในหน่วยความจำ
\' ******************** ข้อมูลที่สมมุติขึ้น************************
\' สมมุติคานปลายยื่นซ้าย
BeamType = 2
L(0) = 2: L(1) = 12: L(2) = 12: L(N) = 10
\' *************************************************************
FitScreen
StepX = 1: StepY = 1 \'กำหนดระยะในการแสดงจุดกริด
Call Form_Activate \' ไปที่เหตุการณ์ Activate
End Sub
----------------------------------------------------------------------------------------------------
Private Sub Form_MouseMove(Button As Integer, Shift AsInteger, X As Single, Y As Single)
\' แสดงตำแหน่งพิกัดที่ StatusBarทศนิยมหนึ่งตำแหน่ง
stbMain.SimpleText = "พิกัดแกน X = " & Format(X,"0.0") & ", พิกัดแกน Y = " & Format(Y,"0.0")
End Sub
---------------------------------------------------------------------------------------------------
2. เมื่อรันโปรแกรมจะแสดงผลดังรูป (สังเกตว่าผมสมมุติBeamType = 2 หมายความว่าคานปลายยื่นซ้ายและความยาวคานรวมเท่ากับ 36 mเพื่อให้สเกลแกน X เท่ากับ |-2|+36+2เท่ากับ 40 m ดังนั้น สเกลแกน Yจึงเท่ากับ |-2|+26+2 เท่ากับ 30 mเพื่อให้เห็นถึงอัตราส่วน 3/4แบบชัดเจน )
หมายเหตุ
ลองปรับความยาวของคานเป็นรูปแบบต่างๆ แล้วดูผลการแสดงภาพนะครับ จะเข้าใจยิ่งขึ้น
การแสดงผลแบบพอดีกับภาพนี้ กรณีความยาวมากๆ ก็จะมีปัญหา ดังนั้น โปรแกรมส่วนใหญ่จะมีทางเลือกในการแสดงผลอีกแบบหนึ่งคือ การเลื่อนจอภาพได้ ซึ่งเทคนิคการเขียนโปรแกรมจะซับซ้อนขึ้น
กรณีการพล็อตที่ความยาวแปรเปลี่ยนทั้งแกน X และแกน Y เช่น กราฟิกโครงข้อหมุน จะมีวิธีปรับสเกลอีกแบบหนึ่งที่ต่างออกไปเล็กน้อย
สำหรับข้อ 2 และ 3 ผมก็จะนำเสนอในตอนต่อๆ ไป นะครับ