static YSRESULT YsClipInfiniteLine2_FindFirstIntersection (YsVec2 &itsc,const YsVec2 &org,const YsVec2 &vec,const YsVec2 &range1,const YsVec2 &range2) { // must have range1<range2 if((YsClipInfinite2DLineByX(itsc,org,vec,range1.x())==YSOK && range1.y()-YsTolerance<itsc.y() && itsc.y()<range2.y()+YsTolerance) || (YsClipInfinite2DLineByX(itsc,org,vec,range2.x())==YSOK && range1.y()-YsTolerance<itsc.y() && itsc.y()<range2.y()+YsTolerance)) { itsc.SetY(YsBound(itsc.y(),range1.y(),range2.y())); return YSOK; } else if((YsClipInfinite2DLineByY(itsc,org,vec,range1.y())==YSOK && range1.x()-YsTolerance<itsc.x() && itsc.x()<range2.x()+YsTolerance) || (YsClipInfinite2DLineByY(itsc,org,vec,range2.y())==YSOK && range1.x()-YsTolerance<itsc.x() && itsc.x()<range2.x()+YsTolerance)) { itsc.SetX(YsBound(itsc.x(),range1.x(),range2.x())); return YSOK; } else { return YSERR; } }
YsColor FsGuiColorDialog::CaptureHSVText(void) const { const double Hd=YsBound(atof(hueText->GetString())/255.0,0.0,1.0); const double Sd=YsBound(atof(saturationText->GetString())/255.0,0.0,1.0); const double Vd=YsBound(atof(valueText->GetString())/255.0,0.0,1.0); YsColor c; c.SetDoubleHSV(Hd,Sd,Vd); return c; }
YsColor FsGuiColorDialog::CaptureRGBText(void) const { const double Rd=YsBound(atof(redText->GetString())/255.0,0.0,1.0); const double Gd=YsBound(atof(greenText->GetString())/255.0,0.0,1.0); const double Bd=YsBound(atof(blueText->GetString())/255.0,0.0,1.0); YsColor c; c.SetDoubleRGB(Rd,Gd,Bd); return c; }
YSRESULT YsTraceLineSegment::SetPositionByParameter(YsLineSegmentTracer &tracer,const double &tt) { double t; t=tt; if(isLoop==YSTRUE) { if(t>1.0) { t=fmod(t,1.0); } else if(t<0.0) { t=1.0-fmod(-t,1.0); } } else { t=YsBound(t,0.0,1.0); } double tDist; tDist=totalLength*t; YSSIZE_T n1,n2; n1=0; n2=segLengthAddUp.GetN()-1; while(n2-n1>1) { YSSIZE_T mid; mid=(n1+n2)/2; if(segLengthAddUp[mid]<tDist) { n1=mid; } else { n2=mid; } } double distRemain; distRemain=tDist-segLengthAddUp[n1]; tracer.segParam=distRemain/segLength[n1]; tracer.segParam=YsBound(tracer.segParam,0.0,1.0); tracer.pos=lSeg[n1]*(1.0-tracer.segParam)+lSeg[n1+1]*tracer.segParam; tracer.seg=(int)n1; return YSOK; }
static YSRESULT YsClipInfiniteLine2_FindSecondIntersection (YsVec2 &itsc,const YsVec2 &firstItsc,const YsVec2 &vec,const YsVec2 &range1,const YsVec2 &range2) { // must have range1<range2 YSRESULT found; double dist,d; YsVec2 candidate; YsVec2 const *range[2]; int i; dist=-1.0; // 0.0 should be OK found=YSERR; range[0]=&range1; range[1]=&range2; for(i=0; i<2; i++) { if(YsClipInfinite2DLineByX(candidate,firstItsc,vec,range[i]->x())==YSOK && range1.y()-YsTolerance<candidate.y() && candidate.y()<range2.y()+YsTolerance) { candidate.SetY(YsBound(candidate.y(),range1.y(),range2.y())); d=(candidate-firstItsc).GetSquareLength(); if(d>=dist) { itsc=candidate; dist=d; found=YSOK; } } if(YsClipInfinite2DLineByY(candidate,firstItsc,vec,range[i]->y())==YSOK && range1.x()-YsTolerance<candidate.x() && candidate.x()<range2.x()+YsTolerance) { candidate.SetX(YsBound(candidate.x(),range1.x(),range2.x())); d=(candidate-firstItsc).GetSquareLength(); if(d>=dist) { itsc=candidate; dist=d; found=YSOK; } } } return found; }
YSRESULT YsShellExt_RoundUtil3d::HalfRoundCorner::SubdivideByStepAngle(const double stepAngle) { const YsVec3 v1=YsUnitVector(roundedCornerPos-center); const YsVec3 v2=YsUnitVector(foot-center); const double fanAngle=acos(YsBound(v1*v2,-1.0,1.0)); return SubdivideByNumberOfSubdivision((int)(0.5+fanAngle/stepAngle)); }
const double YsShellExt_RoundUtil3d::CalculateMaximumRadius(const YsShell &shl) const { if(0==cornerArray.GetN()) { printf("%s %d\n",__FUNCTION__,__LINE__); return 0.0; } double maxRadius=YsInfinity; for(auto corner : cornerArray) { if(YSTRUE==corner.notReallyDistanceLimited) { continue; } YsVec3 toVec=corner.toPos-shl.GetVertexPosition(corner.fromVtHd); const double L=toVec.GetLength(); if(YsTolerance>L) { printf("%s %d\n",__FUNCTION__,__LINE__); return 0.0; } toVec/=L; YsVec3 cenVec=corner.roundDir; if(YSOK!=cenVec.Normalize() || YsTolerance>cenVec*toVec) { printf("%s\n",cenVec.Txt()); printf("%s\n",toVec.Txt()); printf("%lf\n",cenVec*toVec); printf("%s %d\n",__FUNCTION__,__LINE__); return 0.0; } const double theata=acos(YsBound(toVec*cenVec,-1.0,1.0)); const double maxRadiusForCorner=L*tan(theata); if(maxRadiusForCorner<maxRadius) { printf("Max radius limited by %s\n",shl.GetVertexPosition(corner.fromVtHd).Txt()); maxRadius=maxRadiusForCorner; } } return maxRadius; }
YSRESULT YsShellExt_RoundUtil3d::HalfRoundCorner::SubdivideByNumberOfSubdivision(int nDiv) { const YsVec3 v1=YsUnitVector(roundedCornerPos-center); const YsVec3 v2=YsUnitVector(foot-center); const double fanAngle=acos(YsBound(v1*v2,-1.0,1.0)); const YsVec3 axis=YsUnitVector(v2^v1); if(YsOrigin()==v1 || YsOrigin()==v2 || YsOrigin()==axis) { return YSERR; } const YsVec3 baseVec=foot-center; subDiv.CleanUp(); for(int i=0; i<nDiv; ++i) { subDiv.Increment(); if(0==i) { subDiv.Last().vtHd=NULL; subDiv.Last().pos=foot; } else { const double t=(double)i/(double)nDiv; const double angle=fanAngle*t; YsVec3 spokeVec; YsRotation rot(axis,angle); rot.RotatePositive(spokeVec,baseVec); subDiv.Last().vtHd=NULL; subDiv.Last().pos=spokeVec+center; } } return YSOK; }
/*static*/ double YsShellExt_RoundUtil::CalculateRadiusFromTangentDistance(const YsShell &shl,YsShellVertexHandle fromVtHd,const YsShellVertexHandle toVtHd[2],const double dist) { const double edLen[2]= { (shl.GetVertexPosition(toVtHd[0])-shl.GetVertexPosition(fromVtHd)).GetLength(), (shl.GetVertexPosition(toVtHd[1])-shl.GetVertexPosition(fromVtHd)).GetLength() }; const YsVec3 edVec[2]= { (shl.GetVertexPosition(toVtHd[0])-shl.GetVertexPosition(fromVtHd))/edLen[0], (shl.GetVertexPosition(toVtHd[1])-shl.GetVertexPosition(fromVtHd))/edLen[1] }; const double theata=YsPi-acos(YsBound(edVec[0]*edVec[1],-1.0,1.0)); const double t=tan(theata/2.0); if(YsTolerance>t) { return 0.0; } return dist/t; }
void FsGuiColorDialog::UpdateSliderFromText(void) { const double Rd=YsBound(atof(redText->GetString())/255.0,0.0,1.0); const double Gd=YsBound(atof(greenText->GetString())/255.0,0.0,1.0); const double Bd=YsBound(atof(blueText->GetString())/255.0,0.0,1.0); const double Hd=YsBound(atof(hueText->GetString())/255.0,0.0,1.0); const double Sd=YsBound(atof(saturationText->GetString())/255.0,0.0,1.0); const double Vd=YsBound(atof(valueText->GetString())/255.0,0.0,1.0); redSlider->SetPosition(Rd); greenSlider->SetPosition(Gd); blueSlider->SetPosition(Bd); hueSlider->SetPosition(Hd); saturationSlider->SetPosition(Sd); valueSlider->SetPosition(Vd); }
YSRESULT YsShellExt_RoundUtil::CalculateRoundingAll(const YsShell &shl,const double radius,int nDiv) { if(1>nDiv) { nDiv=1; } for(auto &corner : cornerArray) { corner.subDiv[0].CleanUp(); corner.subDiv[1].CleanUp(); const YsVec3 vtPos[3]= { shl.GetVertexPosition(corner.fromVtHd), shl.GetVertexPosition(corner.toVtHd[0]), shl.GetVertexPosition(corner.toVtHd[1]) }; const double edLen[2]= { (shl.GetVertexPosition(corner.toVtHd[0])-shl.GetVertexPosition(corner.fromVtHd)).GetLength(), (shl.GetVertexPosition(corner.toVtHd[1])-shl.GetVertexPosition(corner.fromVtHd)).GetLength() }; const YsVec3 edVec[2]= { (shl.GetVertexPosition(corner.toVtHd[0])-shl.GetVertexPosition(corner.fromVtHd))/edLen[0], (shl.GetVertexPosition(corner.toVtHd[1])-shl.GetVertexPosition(corner.fromVtHd))/edLen[1] }; const double theata=YsPi-acos(YsBound(edVec[0]*edVec[1],-1.0,1.0)); const double L=radius*tan(theata/2.0); if(angleThr>theata) { return YSERR; } YsPlane pln[3]; if(YSOK!=pln[0].MakePlaneFromTriangle(vtPos[0],vtPos[1],vtPos[2])) { return YSERR; } pln[1].Set(vtPos[0]+edVec[0]*L,edVec[0]); pln[2].Set(vtPos[0]+edVec[1]*L,edVec[1]); // Haven't I written three-plane intersection? // Plane equation: // (p-o)*n=0 // pn-on=0 // nx*px+ny*py+nz*pz=on { YsMatrix3x3 mat; YsVec3 rhs; for(int i=0; i<3; ++i) { rhs[i]=pln[i].GetNormal()*pln[i].GetOrigin(); for(int j=0; j<3; ++j) { mat.Set(i+1,j+1,pln[i].GetNormal()[j]); } } if(YSOK!=mat.Invert()) { YsPrintf("Cannot calculate the center.\n"); return YSERR; } corner.center=mat*rhs; } corner.roundedCornerPos=YsUnitVector(vtPos[0]-corner.center); corner.roundedCornerPos=corner.center+corner.roundedCornerPos*radius; for(int edIdx=0; edIdx<2; ++edIdx) { for(int i=0; i<nDiv; ++i) { corner.subDiv[edIdx].Increment(); corner.subDiv[edIdx].Last().vtHd=NULL; if(0==i) { corner.subDiv[edIdx].Last().pos=vtPos[0]+edVec[edIdx]*L;; } if(0<i) { const double t=1.0-(double)i/(double)nDiv; YsVec3 pos=vtPos[0]+edVec[edIdx]*L*t; pos-=corner.center; pos.Normalize(); pos*=radius; pos+=corner.center; corner.subDiv[edIdx].Last().pos=pos; } } } } return YSOK; }
YSRESULT YsTraceLineSegment::MoveByDistance(YsLineSegmentTracer &tracer,const double &dist) { if(dist>0.0) { double distRemain; distRemain=dist; while(distRemain>0.0) { double restOfCurSeg; restOfCurSeg=(1.0-tracer.segParam)*segLength[tracer.seg]; if(distRemain<restOfCurSeg) { tracer.segParam+=distRemain/segLength[tracer.seg]; tracer.segParam=YsBound(tracer.segParam,0.0,1.0); tracer.pos=lSeg[tracer.seg]*(1.0-tracer.segParam)+lSeg[tracer.seg+1]*tracer.segParam; distRemain=0.0; } else { distRemain-=restOfCurSeg; if(tracer.seg<lSeg.GetN()-2) { tracer.seg++; tracer.pos=lSeg[tracer.seg]; tracer.segParam=0.0; } else if(isLoop!=YSTRUE) { tracer.pos=lSeg[tracer.seg+1]; tracer.segParam=1.0; distRemain=0.0; } else { tracer.seg=0; tracer.pos=lSeg[0]; tracer.segParam=0.0; } } } return YSOK; } else if(dist<0.0) { double distRemain; distRemain=-dist; while(distRemain>0.0) { double restOfCurSeg; restOfCurSeg=tracer.segParam*segLength[tracer.seg]; if(distRemain<restOfCurSeg) { tracer.segParam-=distRemain/segLength[tracer.seg]; tracer.segParam=YsBound(tracer.segParam,0.0,1.0); tracer.pos=lSeg[tracer.seg]*(1.0-tracer.segParam)+lSeg[tracer.seg+1]*tracer.segParam; distRemain=0.0; } else { distRemain-=restOfCurSeg; if(tracer.seg>0) { tracer.seg--; tracer.pos=lSeg[tracer.seg+1]; tracer.segParam=1.0; } else if(isLoop!=YSTRUE) { tracer.pos=lSeg[0]; tracer.segParam=0.0; distRemain=0.0; } else { tracer.seg=(int)lSeg.GetN()-2; tracer.pos=lSeg.GetEndItem(); tracer.segParam=1.0; } } } return YSOK; } else { return YSOK; } }