a programmer’s geometry

1、点、线(二维)

1.1、两点间的距离
给定两点K(x1,y1),L(x2, y2),根据勾股定理可得两点间的距离r:
deltaX = x2-x1
deltaY = y2-y1
rsq = deltaX*deltaX+deltaY*deltaY
r = sqrt(rsq) // (1)
但是,这通常不是一个轻便的计算,既要开平方,又要求平方根。

如果只是比较两点间的距离与某个数字的大小,一个简单有效的方法是取而代之比较r*r。
在处理大量比较的前提下,可以减少开平方和平方根的计算的一个行之有效的方法是预先测试:
    如果abs(deltaX)或者abs(deltaY)> 参考值,则两点间距离肯定大于参考值。
    如果abs(deltaX)+abs(deltaY)< 参考值,则两点间距离肯定小于参考值。(两边之和大于第三边)
    
如果deltaX和deltaY的值一个特别大,一个特别小,根据式子(1)得到的值误差可能比较大,此时一个比较稳定的做法是:
absDeltaX = abs(x2-x1)
absDeltaY = abs(y2-y1)
minDelta = min(absDeltaX, absDeltaY)
maxDelta = max(absDeltaX, absDeltaY)
div = minDelta/maxDelta
r = maxDelta*sqrt(1+div*div) // (2)

1.2、直线方程
显示形式:
y = mx+c // (1)
该形式不能表示m趋近于无穷大、垂直水平轴的直线(x=?)。在实际的计算中,该形式的用处不大。
显示形式具有2个常量参数:m,c。

隐式形式:
ax+by+c=0 // (2)
(2)式能表示所有的直线。
如果参数满足条件a*a+b*b=1,则(2)式称为直线的法线(正交)式。
在法线式中,a、b称为方向余弦,即a、b的值分别为从原点到该直线的垂线与x、y轴夹角[0, pi]的余弦;c的绝对值等于原点到该直线的距离(附图):
a = cos(alpha)
b = cos(beta) // sin(alpha)
c = -r
隐式形式具有3个常量参数:a,b,c。

1.3、点到直线的距离
已知一点(x0,y0),和一条直线ax+by+c = 0,两者间的距离为r,则有:
absq = a*a+b*b
sr = a*x0+b*y0+c
r*r = sr*sr/absq

1.4、两条直线的夹角
已知两条直线:
    a1x+b1y+c1 = 0
    a2x+b2y+c2 = 0
则两条直线的夹角angle为:
angle = acos((a1*a2+b1*b2)/(sqrt((a1*a1+b1*b1)(a2*a2+b2*b2))))
如果上述两条直线的方程均是正交形式,则:
angle = acos(a1*a2+b1*b2)

应尽量避免acos计算:如果只是要求计算两条直线的夹角是否落在某个区间(angle1,angle2)范围,则可简化为angle、angle1、angle2三者的余弦比较。(to be tested)
应尽量避免三角函数计算:最小化三角函数计算的方法是将某一角angle的sin、cos、tan等计算,一致转化为tan(angle/2)的计算。

1.5、两条直线的交点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Robert is a famous engineer. One day he was given a task by his boss. The background of the task was the following: Given a map consisting of square blocks. There were three kinds of blocks: Wall, Grass, and Empty. His boss wanted to place as many robots as possible in the map. Each robot held a laser weapon which could shoot to four directions (north, east, south, west) simultaneously. A robot had to stay at the block where it was initially placed all the time and to keep firing all the time. The laser beams certainly could pass the grid of Grass, but could not pass the grid of Wall. A robot could only be placed in an Empty block. Surely the boss would not want to see one robot hurting another. In other words, two robots must not be placed in one line (horizontally or vertically) unless there is a Wall between them. Now that you are such a smart programmer and one of Robert's best friends, He is asking you to help him solving this problem. That is, given the description of a map, compute the maximum number of robots that can be placed in the map. Input The first line contains an integer T (<= 11) which is the number of test cases. For each test case, the first line contains two integers m and n (1<= m, n <=50) which are the row and column sizes of the map. Then m lines follow, each contains n characters of '#', '', or 'o' which represent Wall, Grass, and Empty, respectively. Output For each test case, first output the case number in one line, in the format: "Case :id" where id is the test case number, counting from 1. In the second line just output the maximum number of robots that can be placed in that map.
最新发布
06-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值