|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
如果您觉得本篇CentOSLinux教程讲得好,请记得点击右边漂浮的分享程序,把好文章分享给你的小伙伴们!比来碰到了必要在游戏中绘制多边形trap地区的成绩,经由转化,这个成绩能够分化成更小的怎样绘制三角形的成绩,由于筹划只会供应3个坐标点,然后步伐必需经由过程这三个点来猎取所围成的三角形地区内的一切点的坐标,这个成绩进一步回结为怎样判别点是不是在三角形中,经由了1天的思索,搜刮了一些材料并回想了之前的图形学内容,一样平常来讲判别点是不是在三角形,固然也包含统统多边形,有两种判别***:一种是经由过程点做x轴偏向大概y轴偏向的射线,假如射线与多边形的交点的个数为偶数个则在多边形外,不然多边形内,固然扫除一些边上点和极点的特别情形;另外一种是经由过程盘算多边形的有向面积,然后经由过程点和多边形恣意边组成的一切三角形的有向面积偏向是不是分歧来断定点是不是在三角形中。
可是详细到我们的游戏中,这两种***盘算量都对照年夜,以是我想到了一种主动天生那些属于三角形内的点的体例,复杂来说就是从三角形的年夜角动身,朝向三角形内举行发散,如许处置盘算量小,并且简单了解,这里贴出lua代码,代码对照冗杂,由于写的工夫不长,大概存在必定的bug和必要优化的中央,好比斜率的特别情形等等,以后会持续修正,有喜好的伴侣自取。经由测试,但没有掩盖全体的测试用例,估量会有些bug,但大抵偏向应当是准确的,天生一个具有5000000个点的三角形trap地区只必要1.8秒摆布,固然我前面会持续优化。
--[[
盘算斜率:0和无量年夜的情形简化处置了
]]
functionget_slope(nPosX1,nPosY1,nPosX2,nPosY2,nPosX3,nPosY3)
localnSlope1,nSlope2,nSlope3
ifnPosX1==nPosX2then
nSlope1=99999999--设置一个近似无量斜率
else
nSlope1=(nPosY1-nPosY2)/(nPosX1-nPosX2)
end
ifnPosX2==nPosX3then
nSlope2=99999999
else
nSlope2=(nPosY2-nPosY3)/(nPosX2-nPosX3)
end
ifnPosX3==nPosX1then
nSlope3=99999999
else
nSlope3=(nPosY3-nPosY1)/(nPosX3-nPosX1)
end
ifnSlope1==0then
nSlope1=0.0000001
end
ifnSlope2==0then
nSlope2=0.0000001
end
ifnSlope3==0then
nSlope3=0.0000001
end
returnnSlope1,nSlope2,nSlope3
end
--[[
猎取最长边对应的极点和边判别的按次
]]
functionget_max_angle_pos(tbLine1,tbLine2,tbLine3)
localnMaxLine=math.max(tbLine1[1],tbLine2[1],tbLine3[1])
localtbStartPos={}
localtbSlopeJudge={}
ifnMaxLine==tbLine1[1]then
tbStartPos=tbLine1[2]
table.insert(tbSlopeJudge,tbLine2[3])--前期简化代码
table.insert(tbSlopeJudge,tbLine3[3])
table.insert(tbSlopeJudge,tbLine1[3])
elseifnMaxLine==tbLine2[1]then
tbStartPos=tbLine2[2]
table.insert(tbSlopeJudge,tbLine1[3])
table.insert(tbSlopeJudge,tbLine3[3])
table.insert(tbSlopeJudge,tbLine2[3])
else
tbStartPos=tbLine3[2]
table.insert(tbSlopeJudge,tbLine1[3])
table.insert(tbSlopeJudge,tbLine2[3])
table.insert(tbSlopeJudge,tbLine3[3])
end
returntbStartPos,tbSlopeJudge
end
--[[
猎取肇端点对应的增加偏向
]]
functionget_add_dir(tbStartPos,nMaxX,nMinX,nMaxY,nMinY)
localnAddX=0
localnAddY=0
iftbStartPos[1]==nMaxXthen
nAddX=-1
elseiftbStartPos[1]==nMinXthen
nAddX=1
end
iftbStartPos[2]==nMaxYthen
nAddY=-1
elseiftbStartPos[2]==nMinYthen
nAddY=1
end
returnnAddX,nAddY
end
--[[
奇妙的函数:盘算出对应点与三角形三条线订交的交点,并决意准确的局限
]]
functiongetIntersection(tbSlopeJudge,nPoint,nDir,nMin,nMax)
localtbLimit={}
localnMinC,nMaxC
localnC1,nC2,nC3--交点
if(nDir==1)or(nDir==2)then--x
nC1=math.floor(tbSlopeJudge[1][1]*nPoint+tbSlopeJudge[1][2])
nC2=math.floor(tbSlopeJudge[2][1]*nPoint+tbSlopeJudge[2][2])
nC3=math.floor(tbSlopeJudge[3][1]*nPoint+tbSlopeJudge[3][2])
elseif(nDir==3)or(nDir==4)then--y
nC1=math.floor((nPoint-tbSlopeJudge[1][2])/tbSlopeJudge[1][1])
nC2=math.floor((nPoint-tbSlopeJudge[2][2])/tbSlopeJudge[2][1])
nC3=math.floor((nPoint-tbSlopeJudge[3][2])/tbSlopeJudge[3][1])
end
nMinC,nMaxC=math.min(nC1,nC2),math.max(nC1,nC2)
--用矩形局限加以限定,包管点不超越矩形地区
nMinC=math.max(nMinC,nMin)
nMaxC=math.min(nMaxC,nMax)
--与发散点所对的边的交点假如在这个限定局限内,就截短局限
if(nC3>=nMinC)and(nC3<nMaxC)then
iftbSlopeJudge[3][1]>0then--正斜率且正向增加就交换最年夜局限,负斜率负向增加就交换最小局限
ifmath.fmod(nDir,2)==1then
nMinC=nC3
else
nMaxC=nC3
end
elseiftbSlopeJudge[3][1]<0then
ifmath.fmod(nDir,2)==1then
nMaxC=nC3
else
nMinC=nC3
end
end
end
table.insert(tbLimit,nMinC)
table.insert(tbLimit,nMaxC)
returntbLimit
end
--[[
依照偏向来添补三角形所包括的点
]]
functionfill_***_point(nAddX,nAddY,tbStartPos,tbSlopeJudge,nMinY,nMaxY,nMinX,nMaxX)
localtbTrianglePos={}
localnDir=0
ifnAddX~=0then
--决意x的扩大局限
localnLimitX=0
ifnAddX>0then
nLimitX=nMaxX
nDir=1
elseifnAddX<0then
nLimitX=nMinX
nDir=2
end
forx=tbStartPos[1],nLimitX,nAddXdo
--找出x增添后y被三角形所夹的局限,局限内的点都在三角形内
localtbNode=getIntersection(tbSlopeJudge,x,nDir,nMinY,nMaxY)
fory=tbNode[1],tbNode[2]do
table.insert(tbTrianglePos,{x,y})
end
end
elseifnAddY~=0then
--决意y的扩大局限
localnLimitY=0
ifnAddY>0then
nLimitY=nMaxY
nDir=3
elseifnAddY<0then
nLimitY=nMinY
nDir=4
end
fory=tbStartPos[2],nLimitY,nAddYdo
--找出y增添后x被三角形所夹的局限,局限内的点都在三角形内
localtbNode=getIntersection(tbSlopeJudge,y,nDir,nMinX,nMaxX)
forx=tbNode[1],tbNode[2]do
table.insert(tbTrianglePos,{x,y})
end
end
end
returntbTrianglePos
end
--[[
绘制三角形地区
]]
functioncreate_***(tbPos1,tbPos2,tbPos3)
localnPosX1,nPosY1=unpack(tbPos1)
localnPosX2,nPosY2=unpack(tbPos2)
localnPosX3,nPosY3=unpack(tbPos3)
--找出包抄三角形的最小矩形
localnMaxX=math.max(nPosX1,nPosX2,nPosX3)
localnMinX=math.min(nPosX1,nPosX2,nPosX3)
localnMaxY=math.max(nPosY1,nPosY2,nPosY3)
localnMinY=math.min(nPosY1,nPosY2,nPosY3)
--求出每条边的斜率并处置斜率为无量和0的情形(有优化的计划能够减小此情形下的盘算量)
localnSlope1,nSlope2,nSlope3=get_slope(nPosX1,nPosY1,nPosX2,nPosY2,nPosX3,nPosY3)
--直线方程:y=kx+b
localnB1=nPosY1-nSlope1*nPosX1
localnB2=nPosY2-nSlope2*nPosX2
localnB3=nPosY3-nSlope3*nPosX3
--盘算每条边的长度
localnLine1=math.sqrt((nPosY2-nPosY1)^2+(nPosX2-nPosX1)^2)--pos3
localnLine2=math.sqrt((nPosY3-nPosY2)^2+(nPosX3-nPosX2)^2)--pos1
localnLine3=math.sqrt((nPosY1-nPosY3)^2+(nPosX1-nPosX3)^2)--pos2
--找到最长边对应的谁人极点作为发散肇端点
localtbStartPos,tbSlopeJudge=get_max_angle_pos({nLine1,tbPos3,{nSlope1,nB1}},
{nLine2,tbPos1,{nSlope2,nB2}},
{nLine3,tbPos2,{nSlope3,nB3}})
--判别肇端点所处的地位,决意发散的偏向
localnAddX,nAddY=get_add_dir(tbStartPos,nMaxX,nMinX,nMaxY,nMinY)
--终究到注释了,依据发散偏向顺次盘算在三角形内的点
returnfill_***_point(nAddX,nAddY,tbStartPos,tbSlopeJudge,nMinY,nMaxY,nMinX,nMaxX)
end
如果您觉得本篇CentOSLinux教程讲得好,请记得点击右边漂浮的分享程序,把好文章分享给你的小伙伴们! |
|