ไม่กี่วันนี้ผมได้ถอยเครื่องคิดเลข fx-9860GIII มาหนึ่งเครื่องราคาประมาณสี่พันห้าร้อยบาท ส่วนน้องๆในที่ทำงานถอย fx-9750GIII มาหนึ่งเครื่องเช่นเดียวกันแต่ราคาย่อมเยากว่า ราคาเครื่องประมาณสามพันบาท สองรุ่นนี้เขียนภาษาไพทอนได้ ไพทอนที่ลงในเครื่องคิดเลขเป็นไพทอนรุ่นเล็กเรียกว่า ไมโครไพทอน (Micropython) แต่ไมโครไพทอนที่ลงในเครื่องคิดเลข ทางคาสิโอลงไลบรารีมาให้ใช้แค่สองไลบรารีคือ math และ random ที่อยากได้มากคือไลบรารี io ที่สามารถเขียนอ่านไฟล์ได้กลับไม่ลงมาให้ ทำให้การใช้งานจำกัดจำเขี่ยเหมือนโดนมัดมือมัดเท้า เอาละไม่เป็นไร ผมจะลองเขียนโปรแกรมไพทอนและพยายามใช้ทรัพยากรอันจำกัดจำเขี่ยนี้ให้ออกมาดูดีที่สุด นี่เป็นความท้าทายเล็กๆน้อยๆอย่างหนึ่ง
ณ ตอนนี้มีเครื่องคิดเลขคาสิโอสามรุ่นที่สนับสนุนภาษาไพทอนเรียงกันดังนี้ fx-9750GIII, fx-9860GIII และ fx-cg50
ทดสอบโปรแกรมงานสำรวจที่พัฒนาด้วยภาษาซีบน fx-9750GIII และ fx-9860GIII
ขอย้อนไปโปรแกรมงานสำรวจพื้นฐานบนเครื่องคิดเลข fx-9860GII ที่ผมเขียนด้วยภาษาซี ผมลองเอามาลงในเครื่อง fx-9750III และ fx-9860GIII รันได้ปกติแสดงว่าสถาปัตยกรรมเดียวกัน fx-9860GII ใช้ซีพียู SH4a ส่วนรุ่นอื่นไม่ชัดเจน ความต่างกันที่แน่ๆคือหน่วยความจำ
ชุดโปรแกรมพื้นฐานงานสำรวจ COGO (Coordinate Geometry) ชุดที่ 1
โปรแกรมที่จะเขียนจัดอยู่ในชุด COGO (Coordinate Geometry) ที่มาแก้ปัญหาพิกัดเรขาคณิตในงานสำรวจนั่นเอง ผมเคยเขียนโปรแกรมชุดนี้ด้วยภาษาซีบนเครื่องคิดเลข fx-9860GII (SD) รุ่นก่อน ลองมาดูในภาคภาษาไพทอนบ้าง ผมจะลงซอร์สโค้ดให้ท้ายๆบทความ เผื่อผู้อ่านมีเครื่องคิดเลขรุ่นเหล่านี้จะสามารถก็อปปี้ไปลงเครื่องคิดเลขตัวเองได้
ส่วนประกอบของโปรแกรม
สำหรับโปรแกรมพื้นฐานงานสำรวจในชุดนี้จะจัดโปรแกรมย่อยเล็กๆ ไว้ 4 โปรแกรม
- Bearing-Dist (2 pt) เมื่อกำหนดจุดค่าพิกัด 2 จุด สำหรับคำนวณหามุมอะซิมัทและระยะทาง
- Bearing-Dist(3 pt) เมื่อกำหนดจุดค่าพิกัด 3 จุด สำหรับคำนวณหาง่ามมุมราบ อะซิมัทและระยะทาง ในงานสำรวจก็ได้แก่การตั้งเป้าหลัง (backsight) จุดตั้งกล้อง (station) และเป้าหน้า (target)
- Coordinate 2D เมื่อกำหนดจุดค่าพิกัด 2 จุด กำหนดมุมราบและระยะราบ คำนวณหาค่าพิกัดจุดที่ 3 คำนวณหาพิกัดจุดที่ 3 การคำนวณคำนวณในระนาบสองมิติอย่างเดียว ไม่มีค่าระดับมาเกี่ยวข้อง
- Coordinate 3D เมื่อกำหนดจุดค่าพิกัด 2 จุด กำหนดมุมราบและมุมดิ่ง ระยะทางแบบ slope distance ต้องการคำนวณหาค่าพิกัดและค่าระดับจุดที่ 3
วิธีการใช้งานโปรแกรม
กดคีย์ “MENU” ที่เครื่องคิดเลข กดคีย์ลูกศรเลื่อนไปที่ไอคอน “Python” กดเข้าไป ตรงนี้ผมสร้างโฟลเดอร์ชื่อ “PROGRAM” ผมเอาซอร์สโค้ดโปรแกรมไพทอนมาไว้ที่นี่ เมื่อกด “EXE” เข้าไปจะเห็นไฟล์ซอร์สโค้ดไพทอนเรียงกันประมาณนี้ ตอนนี้จะรันไฟล์ COGOSSE1.py ซึ่งจะต้องมีไฟล์ไลบรารี pbrutils.py ด้วย
เลื่อนแถบเคอร์เซอร์ไปที่ COGOSSE1.py กดคีย์ “F1” หรือกดคีย์ “EXE” จะเห็นเมนู
Bearing-Dist (2 pt)
ที่เมนูกดคีย์ “1” และกดคีย์ “EXE” เป็นการคำนวณหาค่ามุมอะซิมัทและระยะทางเมื่อกำหนดจุดค่าพิกัดให้สองจุด ลองทดสอบจากตัวอย่างดังรูป การประยุกต์ใช้งานส่วนใหญ่เป็นตอนที่ช่างสำรวจตั้งกล้องที่หมุดและส่องไปเป้าหลังหรือเป้าหน้าแล้ววัดระยะทางเพื่อตรวจสอบค่าพิกัดเทียบกับค่าที่คำนวณด้วยเครื่องคิดเลข ทดสอบป้อนค่าและจะได้ผลลัพธ์ออกมา จะได้มุมอะซิมัทจากจุดตั้งกล้องไปเป้าหลัง 15°3′ 34.81″ (ตั้งทิศเหนือที่จุดตั้งต้น ที่นี่หมายถึงจุดตั้งกล้องกวาดมุมตามเข็มนาฬิกาไปหาแขนต้นทาง-ปลายทาง) ระยะทาง 87.395 เมตร กดคีย์ “EXE” อีกครั้งโปรแกรมจะออกมาที่เมนูเดิม
Bearing-Dist (3 pt)
ที่เมนูกดคีย์เลข “2” และกดคีย์ “EXE” การประยุกต์ใช้งานส่วนใหญ่จะเป็นการตั้งกล้องส่องไปหมุดเป้าหลังแล้วป้อนค่าพิกัดเป้าหน้าเพื่อตรวจสอบมุมราบหรือไม่ก็จะเป็นการวางผังโดยการเปิดมุมราบและวัดระยะทางที่เป้าบน pole ลองดูตัวอย่างทดสอบ จะได้ผลลัพธ์มาดังนี้ ครั้งแรกจะแสดงมุมอะซิมัทและระยะทางไปเป้าหลังก่อน ถัดไปจะเป็นมุมราบ มุมอะซิมัทและระยะทางไปเป้าหน้า
Coordinate 2D
ที่เมนูกดคีย์เลข “3” และกดคีย์ “EXE” เป็นการคำนวณหาค่าพิกัดเป้าหน้าเมื่อกำหนดค่าพิกัดจุดตั้งกล้องและเป้าหลัง กำหนดมุมราบและระยะทาง การคำนวณจะไม่มีค่าระดับมาเกี่ยวข้อง จึงเรียกว่า 2D หรือสองมิติ สำหรับโปรแกรมนี้ผมได้นำค่าสเกลแฟคเตอร์เข้ามาช่วยประยุกต์ใช้ด้วย ในกรณีที่ไม่ต้องใช้ก็ป้อนค่าสเกลแฟคเตอร์นี้ เป็น 1.0
สเกลแฟคเตอร์ตัวนี้แล้วจริงๆคือ Combine Scale Factor (CSF) ที่ได้จาก Elevation Scale Factor (ESF) x Grid Scale Factor (GSF) การประยุกต์ใช้สเกลแฟคเตอร์ส่วนใหญ่นำมาใช้โครงการที่ระบบพิกัดฉากกริดยูทีเอ็มในงานใหญ่ๆยาวๆ เช่นโครงการก่อสร้างถนน รถไฟ เพราะว่าแบบ drawing เราอยู่บนระนาบพิกัดฉาก ให้คิดเสียว่าแบบอยู่บนกระดาษขนาดใหญ่มาตราส่วน 1:1 แล้วเราวัดระยะทางบนผิวโลกที่มีความโค้ง ดังนั้นการวัดระยะทางจะต้องมีการทอนจากบนผิวโค้งเพื่อให้ลงมาเข้ากับระนาบพิกัดฉากของกระดาษ มาลองทดสอบข้อมูล ป้อนข้อมูลค่าพิกัดเป้าหลัง ค่าพิกัดจุดต้องกลอง จากนั้นป้อนมุมป้อนระยะทางและสเกลแฟคเตอร์ (ถ้าใช้) แล้วจะได้ผลลัพธ์เป็นค่าพิกัด N=2642985.886, E=231227.370
Coordinate 3D
ที่เมนูกดคีย์ “4” และกดคีย์ “EXE” โปรแกรมคล้าย Coordinate 2D แต่จะมีมิติทางดิ่งเข้ามาเพิ่มดังนั้นที่จุดตั้งกล้องจะวัดความสูงของกล้อง (HI – Height of instrument) และที่เป้าหน้าก็จะต้องวัดความสูงมาด้วย (HT – Height of target) นอกจากนั้นจะมีมุมดิ่ง (Vertical angle) มาด้วย มาดูข้อมูลทดสอบกัน เริ่มจากป้อนค่าพิกัดเป้าหลัง ต่อมาป้อนค่าพิกัดจุดตั้งกล้อง ค่าระดับจุดตั้งกล้อง ความสูงกล้อง ต่อไปป้อนมุมราบ(H.Ang) มุมดิ่ง(V.Ang) ระยะทาง (Slope distance) และความสูงเป้า(HT) และค่าสเกลแฟคเตอร์ (Scale Factor)
โปรแกรมจะคำนวณอะซิมัท ระยะทางจากจุดตั้งกล้องไปเป้าหลัง กดคีย์ “EXE” จะได้ผลลัพธ์ อะซิมัท ระยะราบทั้งระยะบนพื้นโลกและระยะกริดจากจุดตั้งกล้องไปเป้าหน้า สุดท้ายคือผลลัพธ์ที่ต้องการคือค่าพิกัด N=2632215.761, E=232911.782 และค่าระดับ = 6.905 เมตร ของเป้าหน้า
สรุป
ผมเขียนโปรแกรมพื้นฐานงานสำรวจไว้หลายชุด จะทยอยมาลงเป็นซีรี่ย์ ผมเห็นว่ารุ่น fx-9750GIII ราคาประมาณสามพันบาทนั้นไม่ถือว่าแพงมาก สำหรับช่างสำรวจหรือช่างโยธาที่มีการงานเป็นหลักแหล่งสามารถหาซื้อมาใช้งานได้ น้ำหนักเบาจับถนัดมือ
ช่องทางการโปรแกรมมิ่งมีสามช่องทาง ช่องทางที่ 1 คือเขียนด้วยภาษาเบสิคคาสิโอ ก็คล้ายๆกับเครื่องคิดเลขรุ่น fx-5800 อาจจะต่างกันนิดหน่อย ช่องทางที่ 2 คือเขียนด้วยภาษาซี ต้องลงเครื่องมือช่วยพัฒนาโปรแกรม SDK ของคาสิโอ ช่องทางนี้ยากสุดครับ ช่องทางที่ 3 คือเขียนด้วยภาษาไพทอน ที่ผมนำเสนอในบทความนี้ ซึ่งก็ไม่ยากใครมีพื้นฐานโปรแกรมมิ่งภาษาไพทอนนิดๆหน่อยๆก็เขียนได้ ตอนหน้ามาต่อกับโปรแกรมพื้นฐานงานสำรวจชุดที่ 2 (COGO Selected Serie 2) ว่าด้วยเรื่องวงกลมล้วนๆ
มีข้อเตือนใจสำหรับช่างสำรวจสักนิด ปัจจุบันโปรแกรมบนกล้องประมวลผลรวม (Total station) ก็เก่งขึ้นเรื่อยๆ ไม่ต้องกดเครื่องคิดเลขเหมือนสมัยแต่ก่อน ยังมีแอพบนโทรศัพท์มือถือมาช่วยด้วย แต่พื้นฐานจริงๆคือความเข้าใจในเรื่องเรขาคณิต (Geometry) ค่าพิกัด ระยะทาง มุมอะซิมัท จะเกี่ยวข้องกันอย่างแยกกันไม่ออก ดังนั้นต้องทำความเข้าใจหลักวิชาสำรวจให้ลึกซึ้ง เมื่อเข้าใจดีแล้ว การใช้โปรแกรมบนเครื่องคิดเลขหรือบนแอพโทรศัพท์มือถือก็เป็นแค่เครื่องมือที่มาช่วยเหลือให้คำนวณผลลัพธ์มาได้เร็วและถูกต้อง
อนาคตอันใกล้หุ่นยนต์ ปัญญาประดิษฐ์จะมาเร็วกว่าที่คิด หุ่นยนต์หรืออะไรที่มันทำงานแทนเราได้อัตโนมัติ ตัวอย่างคนทำแผนที่ทางอากาศจากโดรนไม่ต้องรู้เรื่อง photogrammetry เลยก็ทำได้ แต่ถ้าคนเราเองไม่ช่วยตัวเองศึกษาค้นคว้า บอกได้คำเดียวว่าเสร็จหุ่นยนต์แน่นอน
วิธีการติดตั้งโปรแกรมบนเครื่องคิดเลข
ผมจะปล่อยซอร์สโค้ดที่อัพเดทไว้ที่เมนูดาวน์โหลด (Download) เมื่อดาวน์โหลดไฟล์ “COGOSSE1.py” และไฟล์ “pbrutils.py” แล้ว สมมุติโหลดมาไว้ที่เครื่องคอมพิวเตอร์ จากนั้นนำเครื่องคิดเลขคาสิโอ fx-9750GIII หรือ fx-9860GIII หรือ fx-cg50 มาเสียบเข้าสาย USB ต่อกับเครื่องคอมพิวเตอร์ ให้กดคีย์ “F1” เพื่อจำลองเป็นไดรว์ จากนั้น copy สองไฟล์นี้เข้าไปที่ไดรว์ของเครื่องคิดเลข รายละเอียดอ่านที่ลิ๊งค์ที่ผมจัดทำมาเป็นพิเศษ
ซอร์สโค้ดโปรแกรมพื้นฐานงานสำรวจชุดที่ 1 (COGOSSE1.py)
from pbrutils import split_angle,deg2dms,DMS2str from pbrutils import calcAzimuth,calcDistance,calcDiff2Angle from pbrutils import calcNextAzimuth,calcNextCoordinate2D from pbrutils import calcNextCoordinate3D from pbrutils import PI,DEG2RAD,RAD2DEG,clear import math def print_menu(): print('COGO Selected Serie 1') print('1: Bearing-Dist(2pt)') print('2: Bearing-Dist(3pt)') print('3: Coordinate 2D') print('4: Coordinate 3D') print('5: Exit') def bearing_dist_2pt(): nbs=float(input("N-BS=" )) ebs=float(input("E-BS=" )) nin=float(input("N-Instr=" )) ein=float(input("E-Instr=" )) azi21=calcAzimuth(nin,ein,nbs,ebs) dist21=calcDistance(nin,ein,nbs,ebs) dazi21=azi21*RAD2DEG print(6*'-',"Output",6*'-') print("Instrument => BS") sn,d,m,s=deg2dms(dazi21) st=DMS2str(d,m,s,2) print("Azimuth=",st) print("Dist=","{0:.3f} m".format(dist21)) input("Press EXE key") def bearing_dist_3pt(): nbs=float(input("N-BS=" )) ebs=float(input("E-BS=" )) nin=float(input("N-Instr=" )) ein=float(input("E-Instr=" )) nfs=float(input("N-FS=" )) efs=float(input("E-FS=" )) azi21=calcAzimuth(nin,ein,nbs,ebs) dist21=calcDistance(nin,ein,nbs,ebs) azi23=calcAzimuth(nin,ein,nfs,efs) dist23=calcDistance(nin,ein,nfs,efs) dazi21=azi21*RAD2DEG dazi23=azi23*RAD2DEG print(6*'-',"Output",6*'-') print("Instrument => BS") sn,d,m,s=deg2dms(dazi21) st=DMS2str(d,m,s,2) print("Azimuth=",st) print("Dist=","{0:.3f} m".format(dist21)) input("Press EXE key") print("Instrument => FS") sn,d,m,s=deg2dms(dazi23) st=DMS2str(d,m,s,2) print("Azimuth=",st) print("Dist=","{0:.3f} m".format(dist23)) hang=RAD2DEG*calcDiff2Angle(azi23,azi21) sn,d,m,s=deg2dms(hang) st=DMS2str(d,m,s,2) print("H Angle=",st) input("Press EXE key") def cooordinate2D(): nbs=float(input("N-BS=?")) ebs=float(input("E-BS=?")) nin=float(input("N-Instr=?")) ein=float(input("E-Instr=?")) ang=input("H Angle=?") hang=split_angle(ang)*DEG2RAD grndist=float(input("Ground Dist=?")) sf=float(input("SF=?")) grddist=sf*grndist azi12=calcAzimuth(nbs,ebs,nin,ein) azi21=calcAzimuth(nin,ein,nbs,ebs) dist21=calcDistance(nin,ein,nbs,ebs) nt,et=calcNextCoordinate2D(nin,ein,azi12,hang,grddist) azi23=calcNextAzimuth(hang,azi12) print(6*'-',"Output",6*'-') print("Instrument => BS") sn,d,m,s=deg2dms(azi21*RAD2DEG) st=DMS2str(d,m,s,2) print("Azimuth=",st) print("Grd Dist=","{0:.3f} m".format(dist21)) print("Instrument => FS") sn,d,m,s=deg2dms(azi23*RAD2DEG) st=DMS2str(d,m,s,2) print("Azimuth=",st) print("Gnd Dist=","{0:.3f} m".format(grndist)) print("Grd Dist=","{0:.3f} m".format(grddist)) input("Press EXE key") print("N=","{0:.3f} m".format(nt)) print("E=","{0:.3f} m".format(et)) input("Press EXE key") def cooordinate3D(): nbs=float(input("N-BS=?")) ebs=float(input("E-BS=?")) nin=float(input("N-Instr=?")) ein=float(input("E-Instr=?")) ele=float(input("Elev=?")) hi=float(input("HI=?")) ang=input("H Angle=?") hang=split_angle(ang)*DEG2RAD ang=input("V Angle=?") vang=split_angle(ang)*DEG2RAD sgrndist=float(input("Slope Dist=?")) sf=1.0 sf=float(input("SF=?")) if sf<1.0: sf=1.0 sgrddist=sgrndist*sf ht=float(input("HT=?")) azi21=calcAzimuth(nin,ein,nbs,ebs) azi12=calcAzimuth(nbs,ebs,nin,ein) dist21=calcDistance(nin,ein,nbs,ebs) azi23=calcNextAzimuth(hang,azi12) nt,et,zt=calcNextCoordinate3D(nin,ein,ele,azi12,hang,vang,sgrddist,hi,ht) print(6*'-',"Output",6*'-') print("Instrument => BS") sn,d,m,s=deg2dms(azi21*RAD2DEG) st=DMS2str(d,m,s,2) print("Azimuth=",st) print("Grd Dist=","{0:.3f} m".format(dist21)) print("Instrument => FS") sn,d,m,s=deg2dms(azi23*RAD2DEG) st=DMS2str(d,m,s,2) print("Azimuth=",st) input("Press EXE key") print("S Gnd Dist= {0:.3f} m".format(sgrndist)) print("S Grd Dist= {0:.3f} m".format(sgrddist)) print("H Gnd Dist= {:.3f} m".format(sgrndist*math.sin(vang))) print("H Grd Dist= {:.3f} m".format(sgrddist*math.sin(vang))) print("Height diff= {:.3f} m".format(zt-ele)) input("Press EXE key") print("N=","{0:.3f} m".format(nt)) print("E=","{0:.3f} m".format(et)) print("Elev=","{0:.3f} m".format(zt)) input("Press EXE key") loop=True choice=-1 ex_choice=-1 while loop: print_menu() choice=int(input('Selection[1-5]')) if (choice==5): loop=False elif (choice==1): loop=True bearing_dist_2pt() ex_choice=1 elif (choice==2): loop=True bearing_dist_3pt() ex_choice=2 elif (choice==3): cooordinate2D() loop=True ex_choice=3 elif (choice==4): loop=True cooordinate3D() ex_choice=4
ไลบรารี pbrutils.py
ตัวไลบรารีนี้ผมเขียนเองบ้าง เก็บเล็กผสมน้อยจากอินเทอร์เน็ต
import math PI=math.pi DEG2RAD=PI/180.0 RAD2DEG=180.0/PI TOLERANCE=1e-10 def clear(): for i in range(6): print() def split_angle(st): ss=st.split('-') j=0 d,m,s=0.0,0.0,0.0 for c in ss: if j==0: d=float(c) elif j==1: m=float(c) elif j==2: s=float(c) j+=1 return d+m/60.0+s/3600.0 def deg2dms(dd): sign=1 if (dd<0): sign=-1 dd=abs(dd) minutes,seconds=divmod(dd*3600,60) degrees,minutes=divmod(minutes,60) return (sign,degrees,minutes,seconds) def DMS2str(degree,minute,second,numdec): degree=abs(degree); minute=abs(minute); second=abs(second) s='{:.%df}' % numdec ss=s.format(second) smin=s.format(60.0) mm='{:.0f}'.format(minute) if (ss==smin): minute+=1 ss=s.format(0.0) if (minute>=60): mm='0' degree+=1 else: mm='{:.0f}'.format(minute) return '{:.0f}'.format(degree)+"-"+mm+"-"+ss def calcDistance(n1,e1,n2,e2): return (math.sqrt(math.pow(n2-n1, 2.0) + math.pow(e2-e1, 2))) def calcAzimuth(n1,e1,n2,e2): """ atan2 not same as excel function""" angle=math.atan2(e2-e1,n2-n1) if angle>=0: return angle else: return angle+2*PI def calcDiff2Angle(azi2,azi1): temp=azi2-azi1 if (temp<0): return temp + 2*PI else: return temp def calcNextAzimuth(currentang,prevazi): temp=currentang+prevazi if (temp<PI): temp=temp+PI elif (temp>3*PI): temp=temp-3*PI else: temp=temp-PI return temp def calcNextCoordinate2D(n,e,prevazi,horang,griddist): nextazi=calcNextAzimuth(horang,prevazi) nt=n+math.cos(nextazi)*griddist et=e+math.sin(nextazi)*griddist return [nt,et] def calcNextCoordinate3D(n,e,z,prevazi,horang,verang,slopedist,hi,ht): hordist=slopedist*math.sin(verang) verdist=slopedist*math.cos(verang) nextazi=calcNextAzimuth(horang,prevazi) nt=n+math.cos(nextazi)*hordist et=e+math.sin(nextazi)*hordist zt=z+hi+verdist-ht return [nt,et,zt] def mean(num): sum_num = 0 for t in num: sum_num = sum_num + t avg = sum_num / len(num) return avg def calcIntersectionFrom4Points(pt1, pt2, pt3, pt4): '''Compute the intersection points which given 4 points. If intersection on line return point otherwise return None. ''' azimuth12 = calcAzimuth(pt1, pt2) distance12 = calcDistance(pt1, pt2) azimuth34 = calcAzimuth(pt3, pt4) distance34 = calcDistance(pt3, pt4) #print('++++ pt1 pt2 pt3 pt4 azimuth12 azimuth34 = ', pt1, pt2, pt3, pt4, azimuth12, azimuth34) if (math.abs(azimuth12 - (0.5 * PI)) <= TOLERANCE) or (math.abs(azimuth12 - (1.5 * PI)) <= TOLERANCE): pti = [(pt1[1] - pt3[1]) * math.tan(azimuth34) + pt3[0], pt1[1]] elif (azimuth34 == (0.5 * PI)) or (azimuth34 == (1.5 * PI)): pti = [(pt3[1] - pt1[1]) * math.tan(azimuth12) + pt1[0], pt3[1]] elif (azimuth34 == azimuth12): return [] else: y = (math.tan(azimuth34) * pt3[1] - math.tan(azimuth12) * pt1[1] + pt1[0] - pt3[0]) / (math.tan(azimuth34) - math.tan(azimuth12)) x = (y - pt1[1]) * math.tan(azimuth12) + pt1[0] pti = [x, y] dist1ni = calcDistance(pt1, pti) dist2ni = calcDistance(pt2, pti) dist3ni = calcDistance(pt3, pti) dist4ni = calcDistance(pt4, pti) if (math.abs((dist1ni + dist2ni) - distance12) <= TOLERANCE) and (math.abs((dist3ni + dist4ni) - distance34) <= TOLERANCE): return pti else: return [] def calcIntersectionAzimuthAzimuth(pt1,azimuth1,pt2,azimuth2): '''Azimuth is radian''' n1=pt1[0] #N e1=pt1[1] #E n2=pt2[0] e2=pt2[1] delty=n2-n1 deltx=e2-e1 ni=(math.tan(azimuth2)*n2-math.tan(azimuth1)*n1+e1-e2)/(math.tan(azimuth2)- math.tan(azimuth1)) ei=(ni-n1)*math.tan(azimuth1)+e1 return [ni,ei] def equation_plane(y1, x1, z1, y2, x2, z2, y3, x3, z3): '''Function to find equation of plane.''' a1 = x2 - x1 b1 = y2 - y1 c1 = z2 - z1 a2 = x3 - x1 b2 = y3 - y1 c2 = z3 - z1 a = b1 * c2 - b2 * c1 b = a2 * c1 - a1 * c2 c = a1 * b2 - b1 * a2 d = (- a * x1 - b * y1 - c * z1) # plane equation is ax + by + cz + d = 0 return [a,b,c,d] def shortest_distance_point_to_plane(y1, x1, z1, a, b, c, d): '''Function to find distance. 3D point to plane.''' d = abs((a * x1 + b * y1 + c * z1 + d)) e = math.sqrt(a * a + b * b + c * c) return d/e def distance_point_to_3Dline(y1,x1,z1,y2,x2,z2,y3,x3,z3): '''3D point y1,x1,z1 3D line from y2,x2,z2 to y3,x3,z3''' b = math.sqrt((x2-x3)**2+(y2-y3)**2+(z2-z3)**2) S = math.sqrt(((y2-y1)*(z3-z1)-(z2-z1)*(y3-y1))**2 + ((z2-z1)*(x3-x1)-(x2-x1)*(z3-z1))**2 + ((x2-x1)*(y3-y1)-(y2-y1)*(x3-x1))**2) / 2.0 return 2*S/b def calcExtend3DLineCoords(n1,e1,z1,n2,e2,z2,dist): lenAB = math.sqrt((n2-n1)**2+(e2-e1)**2+(z2-z1)**2) n3=n2+(n2-n1)/lenAB*dist e3=e2+(e2-e1)/lenAB*dist z3=z2+(z2-z1)/lenAB*dist return [n3,e3,z3] def isect_line_plane_v3_4d(p0, p1, plane, epsilon=1e-6): u = sub_v3v3(p1, p0) dot = dot_v3v3(plane, u) if abs(dot) > epsilon: # Calculate a point on the plane # (divide can be omitted for unit hessian-normal form). p_co=mul_v3_fl(plane,-plane[3]/len_squared_v3(plane)) w = sub_v3v3(p0, p_co) fac = -dot_v3v3(plane, w)/dot ang=math.acos(dot/(math.sqrt(len_squared_v3(plane))*math.sqrt(len_squared_v3(u)))) if ang>math.pi/2.0: ang-=math.pi/2.0 u = mul_v3_fl(u, fac) return add_v3v3(p0, u),ang else: return None,None def area_by_shoelace(x, y): '''Assumes x,y points go around the polygon in one direction''' return abs(sum(i * j for i, j in zip(x, y[1:] + y[:1])) -sum(i * j for i, j in zip(x[1:] + x[:1], y))) / 2 # generic math functions def add_v3v3(v0, v1): return ( v0[0] + v1[0], v0[1] + v1[1], v0[2] + v1[2], ) def sub_v3v3(v0, v1): return ( v0[0] - v1[0], v0[1] - v1[1], v0[2] - v1[2], ) def dot_v3v3(v0, v1): return ( (v0[0] * v1[0]) + (v0[1] * v1[1]) + (v0[2] * v1[2]) ) def len_squared_v3(v0): return dot_v3v3(v0, v0) def mul_v3_fl(v0, f): return ( v0[0] * f, v0[1] * f, v0[2] * f, )
สวัสดีครับ🙏
ขอความอนุเคราะห์หน่อยครับ…
Casio fx-9750 Giii มีวิธีให้เครื่องจำค่าตัวแปรที่เราป้อนค้างไว้เปล่าครับ (โปรแกรมภาษาเบสิคครับ) เหมือนรุ่น 5800 ที่เราไม่ใส่ → หลังเครื่องหมาย ? เครื่องก็จะจำค่าไว้ครับ…เวลาจะกลับไปตรวจดูว่าป้อนผิดหรือเปล่าไม่สะดวกครับ…มือใหม่หัดเขียนครับ😅😅