2011年3月29日星期二

C++程序 判断某一点/区域 是否在另一区域内部

代码中主要包含两个函数


//1. 判断点point是否在区域rgn内部 1--内部 -1--边界 0--外部
template
int isPointInRgn(const mVector &point,
const std::vector > &rgn);

//2. 判断区域B是否在区域A内部
template
bool isRgnInRgn(const std::vector > &rgnB,
const std::vector > &rgnA);


使用时包含下面的头文件,然后直接调用函数即可




/*
利用射线法判断某一点/一个区域 是否属于 另一区域
2011 3 29 http://blog.lyqx.de/?p=592
*/

#ifndef IS_POINT_IN_RGN
#define IS_POINT_IN_RGN

#include
#include

template
struct mVector //代表一个向量或一个坐标点
{
public:
T x,y;

mVector()
: x(0),y(0)
{}

mVector(T a,T b)
{
set(a,b);
}

void set(T a,T b)
{
x=a;
y=b;
}

//向量相加
mVector add(const mVector &right)const
{
return mVector(x+right.x, y+right.y);
}

//向量相减
mVector minus(const mVector &right)const
{
return mVector(x-right.x, y-right.y);
}

//向量点乘
T multipy(const mVector &right)const
{
return x*right.x + y*right.y;
}

//判断两个向量是否平行 0--不平行 1--平行且方向相同 2--平行且方向相反
int isParallel(const mVector &right)const
{
if(x*right.y == y*right.x) //平行
{
if(x) //x!=0
{
if(right.x/x >= 0) return 1;
else return -1;
}
else //x==0
{
if(y)
{
if(right.y/y >= 0) return 1;
else return -1;
}
else {return 1;}
}
}

return 0;
}

//判断两个向量是否相交
bool isIntersect(const mVector &right)const
{
return ! isParallel(right);
}

//判断两个向量是否垂直
bool isPerpendicular(const mVector &right)const
{
return !(this->multipy(right));
}

//获取向量的长度
double getLength()const
{
return std::sqrt(double(x*x + y*y));
}
};

//获取一组点中的下一个点
template
T getNextPoint(const std::vector &rgn, size_t index)
{
if(index == rgn.size()-1 ) return rgn.at(0);
else return rgn.at(index+1);
}

//获取一组点中的上一个点
template
T getPrevPoint(const std::vector &rgn, size_t index)
{
if(0 == index) return rgn.at(rgn.size()-1);
else return rgn.at(index-1);
}

//获取向量的垂直方向 -1--向上 1--向下 0--水平
template
int getVectorDirect(const mVector &vec)
{
if(vec.y > 0) return -1;
else if(vec.y <0) return 1;
else return 0;
}

//判断点point是否在区域rgn内部 1--内部 -1--边界 0--外部
template
int isPointInRgn(const mVector &point, const std::vector > &rgn)
{
int num1=0, num2=0;
for(std::vector >::size_type index=0; index != rgn.size(); index++ )
{
mVector nextPoint = getNextPoint(rgn,index);

if(rgn[index].x else if(nextPoint.minus(point).isParallel( point.minus(rgn[index]) ) == 1)
{
return -1;//点在边界
}
else if(point.y == rgn[index].y) //射线经过边界点
{
mVector prevVector = rgn[index].minus(getPrevPoint(rgn,index)),
nextVector = getNextPoint(rgn,index).minus(rgn[index]);

num2 += getVectorDirect(prevVector) + getVectorDirect(nextVector);


}
else if( (point.y > rgn[index].y && point.y < nextPoint.y)
|| (point.y > nextPoint.y && point.y < rgn[index].y) )
{
++num1;
}
else {}//射线不经过边界线段
}

if((num1 + num2/2)%2) return 1;//奇数
else return 0;
}

//判断区域B是否在区域A内部
template
bool isRgnInRgn(const std::vector > &rgnB, const std::vector > &rgnA)
{
for(std::vector >::size_type index = 0;
index != rgnB.size(); index++)
{
if(! isPointInRgn(rgnB[index], rgnA) ) return false;
}

return true;
}

#endif //IS_POINT_IN_RGN


使用方法演示

#include "isPointInRgn.h"
#include
#include

int main()
{
double x1,y1;

std::vector > borderA,borderB;

std::ifstream finA("in1.txt"), finB("in2.txt");

while(finA>>x1>>y1)
{
borderA.push_back(mVector(x1,y1) );
}

while(finB>>x1>>y1)
{
borderB.push_back(mVector(x1,y1) );

}

std::cout<}


其中in1.txt 和 in2.txt 为输入文件,内容如下

0 0
0 1
0 2
0 3
1 3
2 3
2 2
3 2
4 2
4 3
5 3
5 2
5 1
5 0


1 1
1 2
2 3
2 1


如果发现代码bug请在本页留言

代码下载:http://bit.ly/isPointInRegion
参考文章:判断区域B是否在区域A内部的快速算法 - xiaotie - 博客园

2011年3月21日星期一

短信发送编程接口(飞信API搁浅…)

给大家推荐一个极好用极稳定支持向移动、联通、电信的任意手机号码发送短信的商业服务:推立方
它的发送短信的API也十分简单好用,详见:www.tui3.com/page/smssend

飞信的限制太多了,只能向自己的好友发送短信,而且现在根本没有稳定的接口。所以你可以不读下面的文字。
---------------------分割线-------------------------------------

原文链接:飞信API搁浅…

以前只听说飞信是有API的,经多方查证,其实中国移动飞信并没有像Twitter一样放出API供大家开发使用.

民间存在的一些API均为第三方破解飞信文件然后自己制作的,需经非中国移动飞信服务器中转,基本原理为在URl中传递手机号与密码至第三方服务器,并用一些手段判断手机号与密码是否合乎规定,然后由第三方传递至官方服务器,返回的结果再由第三方间接返回.

这种通过URL传递敏感信息的方式,安全性不言而喻.放下安全性不论,第三方服务器的稳定性也有待验证.加入了这样一个功能产品做出来,不仅有可能泄漏用户的敏感信息,而且连用户是否得到能服务都无法保证.

其实这中间还有一些问题,首先,信息只能在中国移动的手机之间传递,这就限制了一部分用户,然后,发送信息的双方必须是好友,这对某些没有用过飞信的用户来说就是一个挺不小的障碍(教育工作者不知道用的多不多),接下来,我们发信息输入的是对方的手机号(极少有人用飞信号吧…),然而2009年12 月9日中国移动飞信服务器升级,变更了登录地址和部分协议,升级后的协议无法直接给接收方手机号发送短信,只能给飞信号和自己的手机号发送短信,于是第三方就要增加将手机号转换为手机号飞信号的功能(手机号–用户ID–飞信号).
假如……上面这些都不是问题……

中国移动又发飙了…

2010年7月25日(才刚没多久啊),中国移动飞信停止了对低版本PC客户端提供支持,这一举动直接导致几乎所有第三方API无法使用(几乎所有API均在此日期前发布).

飞信停用低版本PC客户端公告:feixin.10086.cn/bulletin/2493/1

经测试不能使用的API中包括传说中由 Google App Engine 强力驱动的

https://fetionapi.appspot.com/
fetionlib.appspot.com

以及由雅虎运营的

pipes.yahoo.com/daibin/fetion

另外,在搜索排行中非常靠前,同样获取一片好评的:

sms.api.bz

sms.yicker.com

至此,目前几乎我能测试的飞信API都不能用了,据说sms.api.bz已经在2010年8月3日恢复正常,经测试,至发表之时仍没有收到所发的信息,假设它已经可以使用,发送与接收之间的延时也使它变得没有使用价值.

至于网友调侃的自己看下串口编程 和AT指令,手动封装DLL,可行性为零,不予考虑.

结论:飞信API陷入窘境,只能期待旧的API被修补或新的第三方API出现…中国移动放出官方API,哈哈,daydream.

个人怨念:

不禁要感慨一下中国现在的业界,一切都被利益驱使,有360与腾讯,金山等之间的纠葛便可一窥,加入大家都学学Facebook,Facebook一直在改动特性和接口,然而却并没有把广告收益看作是最终目的,而是借用广告收益来扩展其他服务,对Facebook公司而言,“让世界更加开放和连结”,这是它的箴言.Facebook向世人提供了一个广阔的平台,希望人们借助这一平台提高效率.所以,Facebook所做出的决定并不是短期的金钱目的,而是为更多用户扩展服务,Facebook的员工毫无掩饰地描绘公司的目标就是:”无处不在”,中心希望国内的公司也能有这样的企业目标.

-----------------以下为个人增加内容-----------------------

目前可用的web版飞信有:
1.官方web飞信:https://webim.feixin.10086.cn
2. sms.bber.info ,随后可能放出API

另外据报道中国移动计划开放飞信平台,4月底公测,6月底正式发布。

2011年3月9日星期三

Javascript 中 setInterval 和 setTimeout函数的使用感受

当需要现在执行一个函数并且每10秒钟执行一次这个函数你会怎么做呢,是不是像下面这样


var func = function(){
//some code
}
func();
window.inter = setInterval(func, 10*1000);


有没有其它的方式呢,下面是我最近的写法


var func = function(){
//some code
window.out = setTimeout(func, 10*1000);
}
func();


本以为code2的方式会更简洁点,但是随后使用的时候就发现问题了,比如如果你想再执行一次这个函数怎么办呢。由于code2的书写方式导致每调用一次func后会造成递归调用,无法停止了。即使clearTimeout(out)也显得有些混乱,因为如果之前连续两次调用func时就会出问题。

以自己的经历给大家一个忠告吧,一个函数尽可能只完成一项功能,像code1那样的方式书写会更好。

2011年3月2日星期三

DOM结构以及HTML中的基本元素

DOM的基本结构:


DOM树

几点说明:
1.DOM的根节点是Document文档,每个载入浏览器的 HTML 文档都会成为 Document 对象,window.document代表了这个对象,也可以用所有基本元素节点的ownerDocument属性获取这个对象。
2.html节点是第二级节点,包含了head和body两个元素节点。

HTML中基本元素拥有的属性(W3C: W3C Standard.)






























































































































































































PropertyDescriptionW3C
attributes[]获取一个元素的所有属性组成的数组Yes
childNodes[]获取一个元素的所有子节点组成的数组Yes
accessKey设置或获取一个元素的快捷键Yes
classNameSets or returns the class attribute of an elementYes
clientHeightReturns the viewable height of the content on a page (not including

borders, margins, or scrollbars)
Yes
clientWidthReturns the viewable width of the content on a page (not including

borders, margins, or scrollbars)
Yes
dirSets or returns the text direction of an elementYes
disabledSets or returns whether an element is disabled, or notYes
firstChildReturns the first child of an elementYes
height设置或获取元素的高度属性Yes
idSets or returns the id of an elementYes
innerHTMLSets or returns the HTML contents (+text) of an elementYes
langSets or returns the language code for an elementYes
lastChild获取一个元素的最后一个子元素Yes
lengthYes
nextSibling获取紧邻元素之后的元素Yes
nodeName获取元素的节点名称 (以大写方式)Yes
nodeType获取元素的节点类型Yes
nodeValue获取元素的值Yes
offsetHeightReturns the height of an element, including borders and padding if any,

but not margins
No
offsetLeftReturns the horizontal offset position of the current element relative

to its offset container
Yes
offsetParentReturns the offset container of an elementYes
offsetTopReturns the vertical offset position of the current element relative to

its offset container
Yes
offsetWidth获取一个元素的宽度,包括补白和边框,不包括边界No
ownerDocument获取一个元素所属的根文档(Document对象)Yes
parentNode获取一个元素的父节点Yes
previousSibling获取紧邻元素之前的元素Yes
scrollHeight获取元素的整体高度(包括滚动条)Yes
scrollLeftReturns the distance between the actual left edge of an element and its

left edge currently in view
Yes
scrollTopReturns the distance between the actual top edge of an element and its

top edge currently in view
Yes
scrollWidth获取元素的整体宽度(包括滚动条)Yes
style设置或获取元素的样式属性Yes
tabIndex设置或获取元素的TAB顺序Yes
tagName以大写字符串的方式获取元素的标签名Yes
title设置或获取元素的标题属性Yes
width设置或获取元素的宽度属性Yes

html中基本元素拥有的方法:
























































































MethodDescriptionW3C
appendChild()在子元素列表后面增加一个新的元素Yes
blur()从一个元素上移除焦点Yes
click()在一个元素上执行点击操作Yes
cloneNode()复制元素Yes
focus()让一个元素成为焦点Yes
getAttribute()Returns the value of an attributeYes
getElementsByTagName()根据指定的标签名获取所有元素Yes
hasChildNodes()返回一个元素是否有子元素Yes
insertBefore()在现存的子元素前插入一个新的子元素Yes
item()基于文档树的位置返回一个元素Yes
normalize()Puts all text nodes underneath this element (including attributes) into

a "normal" form where only structure (e.g., elements, comments, processing

instructions, CDATA sections, and entity references) separates Text nodes,

i.e., there are neither adjacent Text nodes nor empty Text nodes
Yes
removeAttribute()从元素中移除指定的属性Yes
removeChild()移除一个子元素Yes
replaceChild()替换一个子元素Yes
setAttribute()为元素增加新的属性Yes
toString()将一个元素转化为字符串Yes