#include "MGCLStdAfx.h" #include "mg/BezierMove.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif //反対側の方向線の移動(点対象) void moveOppositeControlPoint_reflect( MGBPointSeq& bp, int center_idx, int move_idx, MGPosition new_move_point, bool bClose ){ int npm1=bp.length()-1; int oppo_idx = 2 * center_idx - move_idx;//反対側の点のインデックス if(oppo_idx < 0 || oppo_idx > npm1) if(bClose) oppo_idx = oppo_idx<0 ? oppo_idx+npm1 : oppo_idx-npm1; else return; MGVector diff = bp(center_idx) - bp(move_idx); if(diff.is_zero_vector()) return; bp.store_at(oppo_idx, diff + bp(center_idx)); } MGBezierMove::MGBezierMove( const MGLBRep& bezier, bool Divide, double t_pivot ):m_originalBezier(bezier),m_divide(Divide),m_pivot(t_pivot), m_pivotP(bezier.eval(t_pivot) ){ assert(bezier.is_Bezier(4)); m_closed=bezier.is_closed(); const MGKnotVector& t=bezier.knot_vector(); m_index=t.locate(m_pivot)-3; //m_bIsParallel_s, m_bIsParallel_eの初期化 m_bIsParallel_s = isParallel(bezier.line_bcoef(), m_index); m_bIsParallel_e = isParallel(bezier.line_bcoef(), m_index+3); } //つまみ変形 void MGBezierMove::movePoint( const MGPosition& ToPoint, MGLBRep& mevedBezier ){ //移動の計算 MGVector diff = ToPoint - m_pivotP; //元の曲線の点列 const MGBPointSeq& ori_bp = m_originalBezier.line_bcoef(); mevedBezier=m_originalBezier; //一時描画の曲線の点列 MGBPointSeq& tmp_bp = mevedBezier.line_bcoef(); if(m_divide){ m_bIsParallel_s=m_bIsParallel_e=false;//ここでは一度折れたら復活させない } //始点側を方向線移動 int idp1=m_index+1; tmp_bp.store_at(idp1, ori_bp(idp1)+diff); if(m_bIsParallel_s) moveOppositeControlPoint_reflect(tmp_bp, m_index, idp1, ori_bp(idp1)+diff, m_closed); //終点側を方向線移動 int idp2=m_index+2; tmp_bp.store_at(idp2, ori_bp(idp2) + diff); if(m_bIsParallel_e) moveOppositeControlPoint_reflect(tmp_bp, m_index+3, idp2, ori_bp(idp2)+diff, m_closed); } //与えられたknotの前後の方向線が平行かチェック bool MGBezierMove::isParallel(const MGBPointSeq& bp, int index){ if((index <= 0 || index >= bp.length() - 1)) //indexの前後に点が無い return false; return (bp(index-1)-bp(index)).parallel(bp(index+1)-bp(index)); }