long bench ( void ) { int x0, y0, c; long count=0; while( !( inp( 0x3da ) & 8 ) ); for( c=0; c< 70; c++) { while( ( inp( 0x3da ) & 8 ) ); while( !( inp( 0x3da ) & 8 ) ) { bline( rand()&255, rand()%200, rand()&255, rand()%200, rand()&255 ); count++; } } count=0; for( c=0; c< 70; c++) { while( ( inp( 0x3da ) & 8 ) ); while( !( inp( 0x3da ) & 8 ) ) { bline( rand()&255, rand()%200, rand()&255, rand()%200, rand()&255 ); count++; } } return count; }
Vector3D projection(Vector3D pos,Vector3D go,double angle) { double A,B,C; double a,b,c; bline(go,angle,A,B,C); bline(pos,angle+90,a,b,c); go.x=(b*C-B*c)/(B*a-b*A); go.y=(a*C-A*c)/(A*b-a*B); return(go); }
inline void CurveWarp::sync() { std::vector<synfig::BLinePoint> bline(param_bline.get_list().begin(),param_bline.get_list().end()); Point start_point=param_start_point.get(Point()); Point end_point=param_end_point.get(Point()); curve_length_=calculate_distance(bline); perp_ = (end_point - start_point).perp().norm(); }
static void sng_draw_bright_white_electric_line(float x1, float y1, float x2, float y2, int color) { struct sng_dotted_plot_func_context context; context.i = color; if (!clip_line(&sgc.c, &x1, &y1, &x2, &y2)) return; bline(x1 * sgc.xscale, y1 * sgc.yscale, x2 * sgc.xscale, y2 * sgc.yscale, sng_bright_electric_line_plot_func, &context); }
void sng_draw_electric_line(float x1, float y1, float x2, float y2) { struct sng_dotted_plot_func_context context; context.i = 0; if (!clip_line(&sgc.c, &x1, &y1, &x2, &y2)) return; bline(x1 * sgc.xscale, y1 * sgc.yscale, x2 * sgc.xscale, y2 * sgc.yscale, sng_electric_line_plot_func, &context); }
inline Color CurveGradient::color_func(const Point &point_, int quality, float supersample)const { Point origin=param_origin.get(Point()); Real width=param_width.get(Real()); std::vector<synfig::BLinePoint> bline(param_bline.get_list().begin(), param_bline.get_list().end()); Gradient gradient=param_gradient.get(Gradient()); bool loop=param_loop.get(bool()); bool zigzag=param_zigzag.get(bool()); bool perpendicular=param_perpendicular.get(bool()); bool fast=param_fast.get(bool()); Vector tangent; Vector diff; Point p1; Real thickness; Real dist; float perp_dist; bool edge_case = false; if(bline.size()==0) return Color::alpha(); else if(bline.size()==1) { tangent=bline.front().get_tangent1(); p1=bline.front().get_vertex(); thickness=bline.front().get_width(); } else { float t; Point point(point_-origin); std::vector<synfig::BLinePoint>::const_iterator iter,next; // Figure out the BLinePoints we will be using, // Taking into account looping. if(perpendicular) { next=find_closest(fast,bline,point,t,bline_loop,&perp_dist); perp_dist/=curve_length_; } else // not perpendicular { next=find_closest(fast,bline,point,t,bline_loop); } iter=next++; if(next==bline.end()) next=bline.begin(); // Setup the curve etl::hermite<Vector> curve( iter->get_vertex(), next->get_vertex(), iter->get_tangent2(), next->get_tangent1() ); // Setup the derivative function etl::derivative<etl::hermite<Vector> > deriv(curve); int search_iterations(7); /*if(quality==0)search_iterations=8; else if(quality<=2)search_iterations=10; else if(quality<=4)search_iterations=8; */ if(perpendicular) { if(quality>7) search_iterations=4; } else // not perpendicular { if(quality<=6)search_iterations=7; else if(quality<=7)search_iterations=6; else if(quality<=8)search_iterations=5; else search_iterations=4; } // Figure out the closest point on the curve if (fast) t = curve.find_closest(fast, point,search_iterations); // Calculate our values p1=curve(t); // the closest point on the curve tangent=deriv(t); // the tangent at that point // if the point we're nearest to is at either end of the // bline, our distance from the curve is the distance from the // point on the curve. we need to know which side of the // curve we're on, so find the average of the two tangents at // this point if (t<0.00001 || t>0.99999) { bool zero_tangent = (tangent[0] == 0 && tangent[1] == 0); if (t<0.5) { if (iter->get_split_tangent_angle() || iter->get_split_tangent_radius() || zero_tangent) { // fake the current tangent if we need to if (zero_tangent) tangent = curve(FAKE_TANGENT_STEP) - curve(0); // calculate the other tangent Vector other_tangent(iter->get_tangent1()); if (other_tangent[0] == 0 && other_tangent[1] == 0) { // find the previous blinepoint std::vector<synfig::BLinePoint>::const_iterator prev; if (iter != bline.begin()) (prev = iter)--; else if (loop) (prev = bline.end())--; else prev = iter; etl::hermite<Vector> other_curve(prev->get_vertex(), iter->get_vertex(), prev->get_tangent2(), iter->get_tangent1()); other_tangent = other_curve(1) - other_curve(1-FAKE_TANGENT_STEP); } // normalise and sum the two tangents tangent=(other_tangent.norm()+tangent.norm()); edge_case=true; } } else { if (next->get_split_tangent_angle() || next->get_split_tangent_radius() || zero_tangent) { // fake the current tangent if we need to if (zero_tangent) tangent = curve(1) - curve(1-FAKE_TANGENT_STEP); // calculate the other tangent Vector other_tangent(next->get_tangent2()); if (other_tangent[0] == 0 && other_tangent[1] == 0) { // find the next blinepoint std::vector<synfig::BLinePoint>::const_iterator next2(next); if (++next2 == bline.end()) { if (loop) next2 = bline.begin(); else next2 = next; } etl::hermite<Vector> other_curve(next->get_vertex(), next2->get_vertex(), next->get_tangent2(), next2->get_tangent1()); other_tangent = other_curve(FAKE_TANGENT_STEP) - other_curve(0); } // normalise and sum the two tangents tangent=(other_tangent.norm()+tangent.norm()); edge_case=true; } } } tangent = tangent.norm(); if(perpendicular) { tangent*=curve_length_; p1-=tangent*perp_dist; tangent=-tangent.perp(); } else // not perpendicular // the width of the bline at the closest point on the curve thickness=(next->get_width()-iter->get_width())*t+iter->get_width(); } if(perpendicular) { if(quality>7) { dist=perp_dist; /* diff=tangent.perp(); const Real mag(diff.inv_mag()); supersample=supersample*mag; */ supersample=0; } else { diff=tangent.perp(); //p1-=diff*0.5; const Real mag(diff.inv_mag()); supersample=supersample*mag; diff*=mag*mag; dist=(point_-origin - p1)*diff; } } else // not perpendicular { if (edge_case) { diff=(p1-(point_-origin)); if(diff*tangent.perp()<0) diff=-diff; diff=diff.norm()*thickness*width; } else diff=tangent.perp()*thickness*width; p1-=diff*0.5; const Real mag(diff.inv_mag()); supersample=supersample*mag; diff*=mag*mag; dist=(point_-origin - p1)*diff; } if(loop) dist-=floor(dist); if(zigzag) { dist*=2.0; supersample*=2.0; if(dist>1)dist=2.0-dist; } if(loop) { if(dist+supersample*0.5>1.0) { float left(supersample*0.5-(dist-1.0)); float right(supersample*0.5+(dist-1.0)); Color pool(gradient(1.0-(left*0.5),left).premult_alpha()*left/supersample); if (zigzag) pool+=gradient(1.0-right*0.5,right).premult_alpha()*right/supersample; else pool+=gradient(right*0.5,right).premult_alpha()*right/supersample; return pool.demult_alpha(); } if(dist-supersample*0.5<0.0) { float left(supersample*0.5-dist); float right(supersample*0.5+dist); Color pool(gradient(right*0.5,right).premult_alpha()*right/supersample); if (zigzag) pool+=gradient(left*0.5,left).premult_alpha()*left/supersample; else pool+=gradient(1.0-left*0.5,left).premult_alpha()*left/supersample; return pool.demult_alpha(); } } return gradient(dist,supersample); }
inline void CurveGradient::sync() { std::vector<synfig::BLinePoint> bline(param_bline.get_list().begin(), param_bline.get_list().end()); curve_length_=calculate_distance(bline, bline_loop); }
inline Point CurveWarp::transform(const Point &point_, Real *dist, Real *along, int quality)const { std::vector<synfig::BLinePoint> bline(param_bline.get_list().begin(),param_bline.get_list().end()); Point start_point=param_start_point.get(Point()); Point end_point=param_end_point.get(Point()); Point origin=param_origin.get(Point()); bool fast=param_fast.get(bool()); Real perp_width=param_perp_width.get(Real()); Vector tangent; Vector diff; Point p1; Real thickness; bool edge_case = false; float len(0); bool extreme; float t; if(bline.size()==0) return Point(); else if(bline.size()==1) { tangent=bline.front().get_tangent1(); p1=bline.front().get_vertex(); thickness=bline.front().get_width(); t = 0.5; extreme = false; } else { Point point(point_-origin); std::vector<synfig::BLinePoint>::const_iterator iter,next; // Figure out the BLinePoint we will be using, next=find_closest_to_bline(fast,bline,point,t,len,extreme); iter=next++; if(next==bline.end()) next=bline.begin(); // Setup the curve etl::hermite<Vector> curve(iter->get_vertex(), next->get_vertex(), iter->get_tangent2(), next->get_tangent1()); // Setup the derivative function etl::derivative<etl::hermite<Vector> > deriv(curve); int search_iterations(7); if(quality<=6)search_iterations=7; else if(quality<=7)search_iterations=6; else if(quality<=8)search_iterations=5; else search_iterations=4; // Figure out the closest point on the curve if (fast) t = curve.find_closest(fast, point,search_iterations); // Calculate our values p1=curve(t); // the closest point on the curve tangent=deriv(t); // the tangent at that point // if the point we're nearest to is at either end of the // bline, our distance from the curve is the distance from the // point on the curve. we need to know which side of the // curve we're on, so find the average of the two tangents at // this point if (t<0.00001 || t>0.99999) { bool zero_tangent = (tangent[0] == 0 && tangent[1] == 0); if (t<0.5) { if (iter->get_split_tangent_angle() || iter->get_split_tangent_radius() || zero_tangent) { // fake the current tangent if we need to if (zero_tangent) tangent = curve(FAKE_TANGENT_STEP) - curve(0); // calculate the other tangent Vector other_tangent(iter->get_tangent1()); if (other_tangent[0] == 0 && other_tangent[1] == 0) { // find the previous blinepoint std::vector<synfig::BLinePoint>::const_iterator prev; if (iter != bline.begin()) (prev = iter)--; else prev = iter; etl::hermite<Vector> other_curve(prev->get_vertex(), iter->get_vertex(), prev->get_tangent2(), iter->get_tangent1()); other_tangent = other_curve(1) - other_curve(1-FAKE_TANGENT_STEP); } // normalise and sum the two tangents tangent=(other_tangent.norm()+tangent.norm()); edge_case=true; } } else { if (next->get_split_tangent_angle() || next->get_split_tangent_radius() || zero_tangent) { // fake the current tangent if we need to if (zero_tangent) tangent = curve(1) - curve(1-FAKE_TANGENT_STEP); // calculate the other tangent Vector other_tangent(next->get_tangent2()); if (other_tangent[0] == 0 && other_tangent[1] == 0) { // find the next blinepoint std::vector<synfig::BLinePoint>::const_iterator next2(next); if (++next2 == bline.end()) next2 = next; etl::hermite<Vector> other_curve(next->get_vertex(), next2->get_vertex(), next->get_tangent2(), next2->get_tangent1()); other_tangent = other_curve(FAKE_TANGENT_STEP) - other_curve(0); } // normalise and sum the two tangents tangent=(other_tangent.norm()+tangent.norm()); edge_case=true; } } } tangent = tangent.norm(); // the width of the bline at the closest point on the curve thickness=(next->get_width()-iter->get_width())*t+iter->get_width(); } if (thickness < TOO_THIN && thickness > -TOO_THIN) { if (thickness > 0) thickness = TOO_THIN; else thickness = -TOO_THIN; } if (extreme) { Vector tangent; if (t < 0.5) { std::vector<synfig::BLinePoint>::const_iterator iter(bline.begin()); tangent = iter->get_tangent1().norm(); len = 0; } else { std::vector<synfig::BLinePoint>::const_iterator iter(--bline.end()); tangent = iter->get_tangent2().norm(); len = curve_length_; } len += (point_-origin - p1)*tangent; diff = tangent.perp(); } else if (edge_case) { diff=(p1-(point_-origin)); if(diff*tangent.perp()<0) diff=-diff; diff=diff.norm(); } else diff=tangent.perp(); // diff is a unit vector perpendicular to the bline const Real unscaled_distance((point_-origin - p1)*diff); if (dist) *dist = unscaled_distance; if (along) *along = len; return ((start_point + (end_point - start_point) * len / curve_length_) + perp_ * unscaled_distance/(thickness*perp_width)); }
void move_it_up ( void ) { while( !( inp( 0x3da ) & 8 ) ); bline( x[0], y[0], x[1], y[1], 0 ); x[0]+=sx[0]; y[0]+=sy[0]; x[1]+=sx[1]; y[1]+=sy[1]; if( x[0] < 0 ) { x[0]=0; sx[0]=-sx[0]; } else if( x[0] > 255 ) { x[0]=255; sx[0]=-sx[0]; } if( y[0] < 0 ) { y[0]=0; sy[0]=-sy[0]; } else if( y[0] > 199 ) { y[0]=199; sy[0]=-sy[0]; } if( x[1] < 0 ) { x[1]=0; sx[1]=-sx[1]; } else if( x[1] > 255 ) { x[1]=255; sx[1]=-sx[1]; } if( y[1] < 0 ) { y[1]=0; sy[1]=-sy[1]; } else if( y[1] > 199 ) { y[1]=199; sy[1]=-sy[1]; } bline( x[0], y[0], x[1], y[1], 15 ); }