double BoundedPair::Radious(const int iTap1, const int iTap2, const double dMicR1, const double dMicR2, cv::Point2d &point1, cv::Point2d &point2, CPolygon* poly1, CPolygon *poly2) {//during the computation: point1 & dRadious1 => smaller circle //point2 & dRadious2 => larger circle //bXchange => swap or not bool bXchange1 = false; double dRadi = 0.0; double dDist = std::sqrt((point1.x-point2.x)*(point1.x-point2.x) + (point1.y-point2.y)*(point1.y-point2.y)); double dRadi1 = dMicR1;//min of the given radious if(dMicR1 > dMicR2) { bXchange1 = true; dRadi1 = dMicR2; } double dRate = RateOf(iTap1, iTap2); Point point1Tmp, point2Tmp; std::pair<Point, Point> pairTmp = poly1->CommonEdge(*poly2); Point pointCenter1, pointCenter2; double dRTmp1 = poly1->TriEdgeCircleR(pairTmp.first, pairTmp.second, pointCenter1); double dRTmp2 = poly2->TriEdgeCircleR(pairTmp.first, pairTmp.second, pointCenter2); double dRadi2 = dRTmp1;//min of the new radi bool bXchange2 = false; if(dRTmp1 > dRTmp2) { bXchange2 = true; dRadi2 = dRTmp2; } cv::Point2d pointTmp1, pointTmp2; bool bXchange = false; if(dRadi1 > dRadi2) {//3LineCircle is small dRadi = dRadi2; dDist = std::sqrt((pointCenter1.x()-pointCenter2.x())*(pointCenter1.x()-pointCenter2.x()) + (pointCenter1.y()-pointCenter2.y())*(pointCenter1.y()-pointCenter2.y())); if(bXchange2) { bXchange = true; //pointTmp1 = cv::Point2d(pointCenter2.x(), pointCenter2.y()); //pointTmp2 = cv::Point2d(pointCenter1.x(), pointCenter1.y()); point1 = cv::Point2d(pointCenter2.x(), pointCenter2.y()); point2 = cv::Point2d(pointCenter1.x(), pointCenter1.y()); dRadi1 += dRadi2; dRadi2 = dRadi1 - dRadi2; dRadi1 = dRadi1 - dRadi2; } else { point1 = cv::Point2d(pointCenter1.x(), pointCenter1.y()); point2 = cv::Point2d(pointCenter2.x(), pointCenter2.y()); pointTmp1 = cv::Point2d(pointCenter1.x(), pointCenter1.y()); pointTmp2 = cv::Point2d(pointCenter2.x(), pointCenter2.y()); } } else {//MIC is small dRadi = dRadi1; if(bXchange1) { bXchange = true; cv::Point2d poinTmp = point1; //pointTmp1 = point2; //pointTmp2 = point1; point1 = point2; point2 = poinTmp; // dRadi1 = dMicR2; dRadi2 = dMicR1; } else { //pointTmp1 = point1; //pointTmp2 = point2; dRadi1 = dMicR1; dRadi2 = dMicR2; } } //Radi & circle center computation //dRadi1 ~ point1 | small M //dRadi2 ~ point2 | big N //cross point(dXTmp, dYTmp) double dXTmp, dYTmp; //vectorMN : point1 -> point2 cv::Point2d vectorMN = cv::Point2d((point2.x-point1.x)/dDist, (point2.y-point1.y)/dDist); if( LinesCross(pairTmp.first.x(), pairTmp.first.y(), pairTmp.second.x(), pairTmp.second.y(), pointTmp1.x, pointTmp1.y, pointTmp2.x, pointTmp2.y, dXTmp, dYTmp) ) { if((dDist < dRadi*dRate) && (dDist + std::abs(dRadi2 - dRadi1)) < dRadi*dRate) {//not enought space. dRadi = (dDist + dRadious2 - dRadious1)/dRate; //dDist = dDist + dRadious2 - dRadiou1 dRadi = (dDist + std::abs(dRadi2 - dRadi1))/dRate; } //point1 = crossPoint - 0.5*dRadi*dRate*MN //point2 = crossPoint + 0.5*dRadi*dRate*MN point1.x = dXTmp - vectorMN.x*dRadi*dRate*0.5; point1.y = dYTmp - vectorMN.y*dRadi*dRate*0.5; point2.x = dXTmp + vectorMN.x*dRadi*dRate*0.5; point2.y = dYTmp + vectorMN.y*dRadi*dRate*0.5; } else { std::cerr<< "No cross point"<< std::endl; } //if(dRate == 2) //{ // if((dDist - dRadious1 - dRadious2) > 0 ) // {// got a gap between the 2 circles // std::pair<Point, Point> pairTmp = poly1->CommonEdge(*poly2); // } //} //else //{ //} if(bXchange) { cv::Point2d poinTmp = point1; //pointTmp1 = point2; //pointTmp2 = point1; point1 = point2; point2 = poinTmp; } ClearMapRadi(iTap1, iTap2); return dRadi; }
int cTracer::GetHitNormal(const Vector3f & start, const Vector3f & end, const Vector3i & a_BlockPos) { Vector3i SmallBlockPos = a_BlockPos; char BlockID = m_World->GetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z); if (BlockID == E_BLOCK_AIR || IsBlockWater(BlockID)) { return 0; } Vector3f BlockPos; BlockPos = Vector3f(SmallBlockPos); Vector3f Look = (end - start); Look.Normalize(); float dot = Look.Dot( Vector3f(-1, 0, 0)); // first face normal is x -1 if (dot < 0) { int Lines = LinesCross( start.x, start.y, end.x, end.y, BlockPos.x, BlockPos.y, BlockPos.x, BlockPos.y + 1); if (Lines == 1) { Lines = LinesCross( start.x, start.z, end.x, end.z, BlockPos.x, BlockPos.z, BlockPos.x, BlockPos.z + 1); if (Lines == 1) { intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(-1, 0, 0)); return 1; } } } dot = Look.Dot( Vector3f(0, 0, -1)); // second face normal is z -1 if (dot < 0) { int Lines = LinesCross( start.z, start.y, end.z, end.y, BlockPos.z, BlockPos.y, BlockPos.z, BlockPos.y + 1); if (Lines == 1) { Lines = LinesCross( start.z, start.x, end.z, end.x, BlockPos.z, BlockPos.x, BlockPos.z, BlockPos.x + 1); if (Lines == 1) { intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(0, 0, -1)); return 2; } } } dot = Look.Dot( Vector3f(1, 0, 0)); // third face normal is x 1 if (dot < 0) { int Lines = LinesCross( start.x, start.y, end.x, end.y, BlockPos.x + 1, BlockPos.y, BlockPos.x + 1, BlockPos.y + 1); if (Lines == 1) { Lines = LinesCross( start.x, start.z, end.x, end.z, BlockPos.x + 1, BlockPos.z, BlockPos.x + 1, BlockPos.z + 1); if (Lines == 1) { intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(1, 0, 0), Vector3f(1, 0, 0)); return 3; } } } dot = Look.Dot( Vector3f(0, 0, 1)); // fourth face normal is z 1 if (dot < 0) { int Lines = LinesCross( start.z, start.y, end.z, end.y, BlockPos.z + 1, BlockPos.y, BlockPos.z + 1, BlockPos.y + 1); if (Lines == 1) { Lines = LinesCross( start.z, start.x, end.z, end.x, BlockPos.z + 1, BlockPos.x, BlockPos.z + 1, BlockPos.x + 1); if (Lines == 1) { intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(0, 0, 1), Vector3f(0, 0, 1)); return 4; } } } dot = Look.Dot( Vector3f(0, 1, 0)); // fifth face normal is y 1 if (dot < 0) { int Lines = LinesCross( start.y, start.x, end.y, end.x, BlockPos.y + 1, BlockPos.x, BlockPos.y + 1, BlockPos.x + 1); if (Lines == 1) { Lines = LinesCross( start.y, start.z, end.y, end.z, BlockPos.y + 1, BlockPos.z, BlockPos.y + 1, BlockPos.z + 1); if (Lines == 1) { intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(0, 1, 0), Vector3f(0, 1, 0)); return 5; } } } dot = Look.Dot( Vector3f(0, -1, 0)); // sixth face normal is y -1 if (dot < 0) { int Lines = LinesCross( start.y, start.x, end.y, end.x, BlockPos.y, BlockPos.x, BlockPos.y, BlockPos.x + 1); if (Lines == 1) { Lines = LinesCross( start.y, start.z, end.y, end.z, BlockPos.y, BlockPos.z, BlockPos.y, BlockPos.z + 1); if (Lines == 1) { intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(0, -1, 0)); return 6; } } } return 0; }