haskell 基础题解(50)

点到直线的距离

【题目】给定两个点P1,P2,可以唯一地确定一条直线。另给定一点 P0,求P0到直线的距离。
已知的是3个点。求的结果是一个浮点数。
当 P1= P2 的时候,直线不存在,故无解。其它情况都是有解的。

解法一:
考虑三角形 P0P1P2 的面积为 S, P1 P2 距离为 d,就可求来 高 h,即为解。
三角形面积可用:海伦定理,或三阶生列式。

type Point = (Double, Double)
type Line = (Point, Point)

ptToLine :: Point -> Line -> Maybe Double
ptToLine  (x0,y0) ((x1,y1), (x2,y2)) 
    | dis == 0  = Nothing
    | otherwise = Just (area * 2 / dis)
    where
    dis  = sqrt $ (x2-x1)^2 + (y2-y1)^2
    area = abs(x0*y1 + x1*y2 + x2*y0 - x2*y1 - x1*y0 - x0*y2) * 0.5 

main :: IO ()
main = do
    print $ ptToLine (0,0) ((0,5),(15/4,0))
    print $ ptToLine (4,4) ((5,0),(5,8))

解法二:
在这里插入图片描述
如上图。做向量 v1 = p1->p0, v2 = p1->p2
如果能把这两个向量同时旋转,使得 v2 与 x 轴重合。此时的 v1 的虚部即为所求。
旋转就是复数的乘法,为了保持模不变,乘的应该是个单位复数。它的方向是v2的共轭复数。

import Data.Complex

type Point = (Double, Double)
type Line = (Point, Point)

ptToLine :: Point -> Line -> Maybe Double
ptToLine  (x0,y0) ((x1,y1), (x2,y2)) 
    | v2 == 0  = Nothing
    | otherwise = Just . abs . imagPart $ v1'
    where
    v1 = (x0-x1) :+ (y0-y1)
    v2 = (x2-x1) :+ (y2-y1)
    v2u = conjugate $ v2 / (magnitude v2 :+ 0)
    v1' = v1 * v2u

main :: IO ()
main = do
    print $ ptToLine (0,0) ((0,5),(15/4,0))
    print $ ptToLine (4,4) ((5,0),(5,8))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值