การปรับสเกลหน้าจอแบบพอดีกับกราฟิกคาน อ่าน 4,962

การปรับสเกลหน้าจอแบบพอดีกับกราฟิกคาน

สรกานต์  ศรีตองอ่อน 

ความนำ

   ปัญหาต่อมาในการแสดงกราฟิกคานกรณีเรากำหนดสเกลในการแสดงผลที่หน้าจอแบบคงที่คือเมื่อคานนั้นมีความยาวรวมมากกว่าสเกลที่ตั้งไว้ก็จะทำให้แสดงได้ไม่เต็มภาพวิธีแก้มี 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แบบชัดเจน )

 

หมายเหต

  1. ลองปรับความยาวของคานเป็นรูปแบบต่างๆ แล้วดูผลการแสดงภาพนะครับ จะเข้าใจยิ่งขึ้น

  2. การแสดงผลแบบพอดีกับภาพนี้ กรณีความยาวมากๆ ก็จะมีปัญหา ดังนั้น โปรแกรมส่วนใหญ่จะมีทางเลือกในการแสดงผลอีกแบบหนึ่งคือ การเลื่อนจอภาพได้ ซึ่งเทคนิคการเขียนโปรแกรมจะซับซ้อนขึ้น

  3. กรณีการพล็อตที่ความยาวแปรเปลี่ยนทั้งแกน X และแกน Y เช่น กราฟิกโครงข้อหมุน จะมีวิธีปรับสเกลอีกแบบหนึ่งที่ต่างออกไปเล็กน้อย

  4. สำหรับข้อ 2 และ 3 ผมก็จะนำเสนอในตอนต่อๆ ไป นะครับ

คะแนน:
ร่วมแสดงความคิดเห็น (Post Comment)