Just algorithm!
Triangle Trilemma



ข้อต่อมา TriangleTrilema

ข้อนี้จะให้จุดมา 3 จุด แล้วให้เราบอกว่านี่เป็นสามเหลี่ยมประเภทไหน

โดยต้องบอกว่าเป็นสามเหลี่ยมด้านเท่า (Equilateral) สามเหลี่ยมหน้าจั่ว (Isosceles) หรือสามเหลี่ยมด้านไม่เท่า (Scalene)

และต้องบอกอีกว่า เป็นสามเหลี่ยมมุมป้าน (Obtuse) มุมฉาก (Right) หรือมุมแหลม (Acute)

และบางครั้งถ้าเป็นเส้นตรง หรือเป็นจุดเดียวก็ถือว่าไม่ใช่สามเหลี่ยม

อ่านเพิ่มที่นี่



เริ่มจากการหา ประเภทด้านของสามเหลี่ยม อันนี้เราอาจจะแค่วัดความยาวของแต่ละด้าน

แต่ตรงนี้มีกับดักนิดนึง ถ้าวัดความยาวตัวเลขอาจเป็น float เวลาเปรียบเทียบค่าอาจจะคลาดเคลื่อน

ดังนั้นแทนที่เราจะวัดความยาว เรามาหาพื้นที่สี่เหลี่ยมจตุรัสของแต่ละด้าน

สูตรการหาพื้นที่คือ
let area (x1, y1) (x2, y2) =
    let deltaX = x1 - x2
    let deltaY = y1 - y2
    (deltaX * deltaX) + (deltaY * deltaY)

ถัดมา มาหาประเภทด้านของสามเหลี่ยม
let typeSide areas =
    let count = areas |> Seq.distinct
                      |> Seq.length
    match count with
    | 1 -> "equilateral"
    | 2 -> "isosceles"
    | 3 -> "scalene"

เราก็วัดขนาดพื้นที่ ถ้าเท่ากันหมด ก็ equilateral

ถ้าเท่ากัน 2 ด้านก็ isosceles

ถ้าไม่เท่ากันเลยก็ scalene



คราวนี้เรามาวัดมุม
let typeAngle areas =
    let sorted = Array.sort areas
    match compare (sorted.[0+ sorted.[1]) sorted.[2with
    | -1 -> "obtuse"
    | 0  -> "right"
    | 1  -> "acute"

ถ้าเป็นมุมฉากก็ง่ายมาก เรารู้ว่าพื้นที่ด้าน A + B = C เสมอ (right)

จริงๆ คิดต่อก็ไม่ยาก ถ้า A + B > C แปลว่า C มีพื้นที่แคบ จึงเป็นสามเหลี่ยมมุมแหลม (acute)

ถ้า A + B < C แปลว่า C มีพื้นที่กว้าง จึงเป็นสามเหลี่ยมมุมป้าน (obtuse)



ถัดมา เรามาหาว่าถ้าสามเหลี่ยมอยู่ระนาบเดียวกันหมด ก็ไม่ใช่สามเหลี่ยม
let (|Collinear|Triangle|) ((x1, y1), (x2, y2), (x3, y3)) =
    if (x1 - x2) * (y1 - y3) = (x1 - x3) * (y1 - y2) 
    then Collinear
    else Triangle

ด้านบนเป็น feature ของ f# ชื่อว่า Active Patterns

วิธีการหาก็ใช้สูตรหาความชัน ถ้าความชันเท่ากันก็ถือว่าเป็นระนาบเดียวกัน

ที่จริงสูตรหาความชันต้องเป็นหาร (x1 - x2) / (x1 - x3) = (y1 - y2) / (y1 - y3)

แต่เพียงแค่เอามาคูณสลับ เพื่อไม่อยากให้ type เป็น float



เรามาเริ่มคำนวนกันเลย
let solve p1 p2 p3 =
    match p1, p2, p3 with
    | Collinear -> "not a triangle"
    | Triangle  -> let areas = [| area p1 p2; area p2 p3; area p3 p1 |]
                   sprintf "%s %s triangle" (typeSide areas) (typeAngle areas)

โดย p1 = (x1, y1), p2 = (x2, y2), p3 = (x3, y3)

เข้าสูตรต่างๆ ด้านบนก็ได้ผลลัพธ์ออกมา



จบ



Create Date : 01 มิถุนายน 2557
Last Update : 1 มิถุนายน 2557 11:16:30 น. 0 comments
Counter : 1250 Pageviews.

ชื่อ :
Comment :
  *ใช้ code html ตกแต่งข้อความได้เฉพาะสมาชิก
 

chaowman
Location :
กรุงเทพฯ Thailand

[Profile ทั้งหมด]

ฝากข้อความหลังไมค์
Rss Feed
Smember
ผู้ติดตามบล็อก : 8 คน [?]





New Comments
Group Blog
 
All Blogs
 
Friends' blogs
[Add chaowman's blog to your web]
Links
 

 Pantip.com | PantipMarket.com | Pantown.com | © 2004 BlogGang.com allrights reserved.