首页 \ 问答 \ 草像beziercurve上的平滑动画?(Grass like smoothing animation on beziercurve?)

草像beziercurve上的平滑动画?(Grass like smoothing animation on beziercurve?)

这是我想要实现的 - GRASS动画 (期望的动画)

这是该项目目前的地位 - 我的头发动画

这是上面代码的更结构化的代码 - 我的头发动画(由markE)-- markE的头发动画代码

问题: -

我可以给头发提供动作,但是动画应该更像波浪般的草,像自由流动一样。现在不是很流畅。可以做些什么来使头发以更自然的方式流动。 如果可能的话,请给我一个小样本!!!

    <canvas id="myCanvas" width="500" height="500" style="background-color: antiquewhite" ></canvas>

JAVASCRIPT

//mouse position
var x2=0;
var y2=0;

window.addEventListener("mousemove",function(){moving(event);init()},false)

//these variables define the bend in our bezier curve
var bend9=0;
var bend8=0;
var bend7=0;
var bend6=0;
var bend5=0;
var bend4=0;
var bend3=0;
var bend2=0;
var bend1=0;

//function to get the mouse cordinates
function moving(event) {
    bend_value();//this function is defined below
    try
    {
        x2 = event.touches[0].pageX;
        y2 = event.touches[0].pageY;
    }
    catch (error)
    {
        try
        {
            x2 = event.clientX;
            y2 = event.clientY;
        }
        catch (e)
        {
        }
    }

    try
    {
        event.preventDefault();
    }
    catch (e)
    {
    }
    if(between(y2,204,237) && between(x2,115,272))
    {
    console.log("Xmove="+x2,"Ymove="+y2)
    }

}

//function for declaring range of bezier curve
function between(val, min, max)
{
    return val >= min && val <= max;
}

(function() {
    hair = function() {
        return this;
    };

    hair.prototype={

     draw_hair:function(a,b,c,d,e,f,g,h){

            var sx  =136+a;//start position of curve.used in moveTo(sx,sy)
            var sy  =235+b;
            var cp1x=136+c;//control point 1
            var cp1y=222+d;
            var cp2x=136+e;//control point 2
            var cp2y=222+f;
            var endx=136+g;//end points
            var endy=210+h;

         var canvas = document.getElementById('myCanvas');
         var context = canvas.getContext('2d');
//         context.clearRect(0, 0,500,500);
         context.strokeStyle="grey";
         context.lineWidth="8";
         context.beginPath();
         context.moveTo(sx,sy);
         context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,endx,endy);
         context.lineCap = 'round';
         context.stroke();
//         context.restore();
//         context.save();
    }
};
})();

//this function provides and calculate the bend on mousemove
function bend_value(){
    var ref1=135;//this is ref point for  hair or curve no 1
    var ref2=150;//hair no 2 and so on
    var ref3=165;
    var ref4=180;
    var ref5=195;
    var ref6=210;
    var ref7=225;
    var ref8=240;
    var ref9=255;
if(between(x2,115,270) && between(y2,205,236))
{
    if(x2>=135 && x2<=145){bend1=(x2-ref1)*(2.2);}
    if(x2<=135 && x2>=125){bend1=(x2-ref1)*(2.2);}

    if(x2>=150 && x2<=160){bend2=(x2-ref2)*(2.2);}
    if(x2<=150 && x2>=140){bend2=(x2-ref2)*(2.2);}

    if(x2>=165 && x2<=175){bend3=(x2-ref3)*(2.2);}
    if(x2<=165 && x2>=155){bend3=(x2-ref3)*(2.2);}

    if(x2>=180 && x2<=190){bend4=(x2-ref4)*(2.2);}
    if(x2<=180 && x2>=170){bend4=(x2-ref4)*(2.2);}

    if(x2>=195 && x2<=205){bend5=(x2-ref5)*(2.2);}
    if(x2<=195 && x2>=185){bend5=(x2-ref5)*(2.2);}

    if(x2>=210 && x2<=220){bend6=(x2-ref6)*(2.2);}
    if(x2<=210 && x2>=200){bend6=(x2-ref6)*(2.2);}

    if(x2>=225 && x2<=235){bend7=(x2-ref7)*(2.2);}
    if(x2<=225 && x2>=215){bend7=(x2-ref7)*(2.2);}

    if(x2>=240 && x2<=250){bend8=(x2-ref8)*(2.2);}
    if(x2<=240 && x2>=230){bend8=(x2-ref8)*(2.2);}

    if(x2>=255 && x2<=265){bend9=(x2-ref9)*(2.2);}
    if(x2<=255 && x2>=245){bend9=(x2-ref9)*(2.2);}
    }
}

function init(){//this function draws each hair/curve
    var canvas = document.getElementById('myCanvas');
    var context = canvas.getContext('2d');
    var clear=context.clearRect(0, 0,500,500);
    var save=context.save();

//   /* console.log("bend2="+bend2)
//    console.log("bend3="+bend3)
//    console.log("bend4="+bend4)
//    console.log("bend5="+bend5)
//    console.log("bend6="+bend6)
//    console.log("bend7="+bend7)
//    console.log("bend8="+bend8)
//    console.log("bend9="+bend9)*/

    hd1 = new hair();//hd1 stands for hair draw 1.this is an instance created for drawing hair no 1
    clear;
    hd1.draw_hair(0,0,0,0,0,0,0+bend1/2,0);//these parameters passed to function drawhair and bend is beint retrieved from function bend_value()
    save;

    hd2 = new hair();
    clear;
    hd2.draw_hair(15,0,15,0,15,0,15+bend2/2,0);
    save;

    hd3 = new hair();
    clear;
    hd3.draw_hair(30,0,30,0,30,0,30+bend3/2,0);
    save;

    hd4 = new hair();
    clear;
    hd4.draw_hair(45,0,45,0,45,0,45+bend4/2,0);
    save;

    hd5 = new hair();
    clear;
    hd5.draw_hair(60,0,60,0,60,0,60+bend5/2,0);
    save;
 }

window.onload = function() {
    init();
    disableSelection(document.body)
}

function disableSelection(target){
    if (typeof target.onselectstart!="undefined") //IE
        target.onselectstart=function(){return false}
    else if (typeof target.style.MozUserSelect!="undefined") //Firefox
        target.style.MozUserSelect="none"
    else //All other ie: Opera
        target.onmousedown=function(){return false}
    target.style.cursor = "default"
}

This is what I am trying to achieve--GRASS Animation(Desired animation)

This is where the project is standing currently --My hair animation

This is a more structurised code of the above code --My hair animation(by markE)--markE`s code of hair animation

PROBLEM:--

I am able to give movements to hairs but animation should be more like wavy grass like freeflowing.Its not very smooth now.What can be done to make the hairs flow in more natural manner. Please provide me with a small sample if possible!!!

    <canvas id="myCanvas" width="500" height="500" style="background-color: antiquewhite" ></canvas>

JAVASCRIPT

//mouse position
var x2=0;
var y2=0;

window.addEventListener("mousemove",function(){moving(event);init()},false)

//these variables define the bend in our bezier curve
var bend9=0;
var bend8=0;
var bend7=0;
var bend6=0;
var bend5=0;
var bend4=0;
var bend3=0;
var bend2=0;
var bend1=0;

//function to get the mouse cordinates
function moving(event) {
    bend_value();//this function is defined below
    try
    {
        x2 = event.touches[0].pageX;
        y2 = event.touches[0].pageY;
    }
    catch (error)
    {
        try
        {
            x2 = event.clientX;
            y2 = event.clientY;
        }
        catch (e)
        {
        }
    }

    try
    {
        event.preventDefault();
    }
    catch (e)
    {
    }
    if(between(y2,204,237) && between(x2,115,272))
    {
    console.log("Xmove="+x2,"Ymove="+y2)
    }

}

//function for declaring range of bezier curve
function between(val, min, max)
{
    return val >= min && val <= max;
}

(function() {
    hair = function() {
        return this;
    };

    hair.prototype={

     draw_hair:function(a,b,c,d,e,f,g,h){

            var sx  =136+a;//start position of curve.used in moveTo(sx,sy)
            var sy  =235+b;
            var cp1x=136+c;//control point 1
            var cp1y=222+d;
            var cp2x=136+e;//control point 2
            var cp2y=222+f;
            var endx=136+g;//end points
            var endy=210+h;

         var canvas = document.getElementById('myCanvas');
         var context = canvas.getContext('2d');
//         context.clearRect(0, 0,500,500);
         context.strokeStyle="grey";
         context.lineWidth="8";
         context.beginPath();
         context.moveTo(sx,sy);
         context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,endx,endy);
         context.lineCap = 'round';
         context.stroke();
//         context.restore();
//         context.save();
    }
};
})();

//this function provides and calculate the bend on mousemove
function bend_value(){
    var ref1=135;//this is ref point for  hair or curve no 1
    var ref2=150;//hair no 2 and so on
    var ref3=165;
    var ref4=180;
    var ref5=195;
    var ref6=210;
    var ref7=225;
    var ref8=240;
    var ref9=255;
if(between(x2,115,270) && between(y2,205,236))
{
    if(x2>=135 && x2<=145){bend1=(x2-ref1)*(2.2);}
    if(x2<=135 && x2>=125){bend1=(x2-ref1)*(2.2);}

    if(x2>=150 && x2<=160){bend2=(x2-ref2)*(2.2);}
    if(x2<=150 && x2>=140){bend2=(x2-ref2)*(2.2);}

    if(x2>=165 && x2<=175){bend3=(x2-ref3)*(2.2);}
    if(x2<=165 && x2>=155){bend3=(x2-ref3)*(2.2);}

    if(x2>=180 && x2<=190){bend4=(x2-ref4)*(2.2);}
    if(x2<=180 && x2>=170){bend4=(x2-ref4)*(2.2);}

    if(x2>=195 && x2<=205){bend5=(x2-ref5)*(2.2);}
    if(x2<=195 && x2>=185){bend5=(x2-ref5)*(2.2);}

    if(x2>=210 && x2<=220){bend6=(x2-ref6)*(2.2);}
    if(x2<=210 && x2>=200){bend6=(x2-ref6)*(2.2);}

    if(x2>=225 && x2<=235){bend7=(x2-ref7)*(2.2);}
    if(x2<=225 && x2>=215){bend7=(x2-ref7)*(2.2);}

    if(x2>=240 && x2<=250){bend8=(x2-ref8)*(2.2);}
    if(x2<=240 && x2>=230){bend8=(x2-ref8)*(2.2);}

    if(x2>=255 && x2<=265){bend9=(x2-ref9)*(2.2);}
    if(x2<=255 && x2>=245){bend9=(x2-ref9)*(2.2);}
    }
}

function init(){//this function draws each hair/curve
    var canvas = document.getElementById('myCanvas');
    var context = canvas.getContext('2d');
    var clear=context.clearRect(0, 0,500,500);
    var save=context.save();

//   /* console.log("bend2="+bend2)
//    console.log("bend3="+bend3)
//    console.log("bend4="+bend4)
//    console.log("bend5="+bend5)
//    console.log("bend6="+bend6)
//    console.log("bend7="+bend7)
//    console.log("bend8="+bend8)
//    console.log("bend9="+bend9)*/

    hd1 = new hair();//hd1 stands for hair draw 1.this is an instance created for drawing hair no 1
    clear;
    hd1.draw_hair(0,0,0,0,0,0,0+bend1/2,0);//these parameters passed to function drawhair and bend is beint retrieved from function bend_value()
    save;

    hd2 = new hair();
    clear;
    hd2.draw_hair(15,0,15,0,15,0,15+bend2/2,0);
    save;

    hd3 = new hair();
    clear;
    hd3.draw_hair(30,0,30,0,30,0,30+bend3/2,0);
    save;

    hd4 = new hair();
    clear;
    hd4.draw_hair(45,0,45,0,45,0,45+bend4/2,0);
    save;

    hd5 = new hair();
    clear;
    hd5.draw_hair(60,0,60,0,60,0,60+bend5/2,0);
    save;
 }

window.onload = function() {
    init();
    disableSelection(document.body)
}

function disableSelection(target){
    if (typeof target.onselectstart!="undefined") //IE
        target.onselectstart=function(){return false}
    else if (typeof target.style.MozUserSelect!="undefined") //Firefox
        target.style.MozUserSelect="none"
    else //All other ie: Opera
        target.onmousedown=function(){return false}
    target.style.cursor = "default"
}

原文:https://stackoverflow.com/questions/17171010
更新时间:2023-05-10 13:05

最满意答案

 D TblAryDs        DS                  qualified dim(9999)                    
 D  key
 D    tblName                     3a   overlay(key)                                        
 D    tblElement                 10a   overlay(key:*next)                                        
 D    tblDivision                 5a   overlay(key:*next)                                        
 D  tblRes                        2a           

  /FREE
    idx = %lookup(tblName + tblElement + tblDivision 
                  :TblAryDs(*).key); 
    if idx > *ZEROS;
      return TblAryDs(idx).tblRes;
    endif; 
  /END-FREE  

注意:如上所示, %LOOKUP()将搜索所有9999个元素。 如果必须重复搜索不同的值,请将ASCEND关键字添加到数组中,并在搜索之前使用SORTA进行排序。 最后,跟踪阵列中实际使用的元素数量。

idx = %lookup(tblName + tblElement + tblDivision 
                  : TblAryDs(*).key : nbrElemUsed);

这样, %LOOKUP()%将仅对活动元素执行更快的二进制搜索。


 D TblAryDs        DS                  qualified dim(9999)                    
 D  key
 D    tblName                     3a   overlay(key)                                        
 D    tblElement                 10a   overlay(key:*next)                                        
 D    tblDivision                 5a   overlay(key:*next)                                        
 D  tblRes                        2a           

  /FREE
    idx = %lookup(tblName + tblElement + tblDivision 
                  :TblAryDs(*).key); 
    if idx > *ZEROS;
      return TblAryDs(idx).tblRes;
    endif; 
  /END-FREE  

Note: as coded above, %LOOKUP() will search all 9999 elements. If you have to search repeatedly for different values, add the ASCEND keyword to the array and use SORTA to sort it prior to searching. Lastly, keep track of how many elements are actually used in the array.

idx = %lookup(tblName + tblElement + tblDivision 
                  : TblAryDs(*).key : nbrElemUsed);

This way %LOOKUP()% will perform a much faster binary search of only the active elements.

相关问答

更多
  • 您可以从数组中提取的details.device_id $lookup 。 要从常规字段进行$lookup ,您可以在$match之后放置$lookup : NotificationSchema.aggregate([{ $match: condition }, { $lookup: { from: "vehicles", localField: "device_id", foreignField: "device_id", a ...
  • 如果通过恒定的内存开销,则意味着对于存储在数据结构中的N元素,空间消耗应该是O(N) ,那么任何平衡树都会这样做 - 事实上,任何n树都会将元素存储在外部叶子,其中n > 1并且每个外部树都包含一个元素,具有此属性。 这是由于任何有N节点的树形图都有N - 1边缘。 如果通过恒定的内存开销,则意味着对于N元素,空间消耗应该是N + O(1) ,那么平衡树和哈希表都不具有此属性 - 两者都将使用k * N内存,其中k > 1由于在树的情况下额外的节点指针以及在散列表的情况下的加载因子。 我发现你的方法很有趣, ...
  • 最有效的方法是使用一套。 构建一组所有书名并找到名称和someBooks书籍的交集。 let allNames = new Set(lookups.Data.map(e => e.BookName)), someBooks = new Set(["ABC", "CED", "Silapathikaram"]); let intersection = new Set(); for (var elem of allNames) { if (someBooks.has(elem)) { ...
  • 你的类型定义有错误。 我很确定你想要的是: type 'a vertex = |Empty |Vertex of 'a * 'a vertex list 您可以使用let rec来定义此类型的值: let rec v0 = Vertex(0, [v1]) and v1 = Vertex(1, [v0]) 根据我的经验,处理这类价值很困难。 OCaml是一种渴望的语言,因此很难用循环值进行计算。 对于第二个问题,编译器试图告诉你, array本身不是一个类型。 你需要说出它是一个数组。 type ...
  • 通常情况下,答案是:这取决于。 你是否需要一些高级查询,比如y列中的值大于23的x列中所有值的总和。如果是这样,内存SQL数据库就派上用场了。 否则就会有点矫枉过正。 假设数据库不在讨论范围内,接下来的问题是:您是否需要单个值,完整(或大部分)的列或行? 什么是你的列和行的自然“名字”。 以下是一些选项: “名称”是连续的整数 :使用二维数组(我不会在Java中经常使用数组,但是在固定长度的只读情况下,其他所有内容听起来都有很大的开销。通过选择索引的顺序,即行首先与列首先你可以得到完整的列/行非常简单和高效 ...
  • 字典通常以两种方式实现,哈希映射或二叉树。 1:如果字典是二叉树,则搜索时间是二进制搜索,因此是O(log n)。 如果字典是哈希映射,则搜索时间是O(1)。 (对于具有相同哈希值的键,可能会增加到O(m)) 2:你是对的,在这种稀疏数据集的情况下,字典将更好地利用空间。 字典搜索的额外时间成本相对较低。 使用字典可以进一步改进使用字典搜索(如果平均情况是哈希映射中不存在的对象)。 Dictionaries are usually implemented in two ways, a hash map or ...
  • D TblAryDs DS qualified dim(9999) D key D tblName 3a overlay(key) D tblElement 10a overlay(key:*next) ...
  • 在Firebase中,您可以使用单个值或值范围进行查询,因此构建单个查询以获取与多个关键字匹配的项目是不可能的。 但是,您可以安排数据库,以便轻松查询或单个关键字。 然后,您需要组合多个查询等。 您可以像这样安排您的数据: { "items": { "item1_id": { "brand_id": ..., "itemName": ..., "price": ..., "keywords": { "black": true, ...
  • 把它放在你的班级声明中: std::vector stops; 其中stop是包含stop定义的类/结构。 stops是一个动态数组,可以管理自己的大小。 Put this in your class declaration: std::vector stops; where stop is a class/structure containing the definition of a stop. stops is a dynamic array that will manag ...
  • 当然。 制作一个字典对象 dict = { string1: 1, string2: 1, etc 它保证提供O(1)查找时间。 Sure. Make an dictionary object dict = { string1: 1, string2: 1, etc It's guaranteed to provide O(1) lookup time.

相关文章

更多

最新问答

更多
  • 以编程方式创建视频?(Create videos programmatically?)
  • 为什么开机慢上面还显示;Inetrnet,Explorer
  • javascript数组,如何改变这个数组结构(javascript arrays, how to change this array structure)
  • 在ASP.NET Web API中使用多个Get方法进行路由(Routing with multiple Get methods in ASP.NET Web API)
  • 用于backbone.js验证的自定义验证器(Custom validator for backbone.js validation)
  • const char *与其他指针有什么不同?(Is const char * different from other pointers? [duplicate])
  • 无效的列索引,使用PreparedStatement更新(Invalid column index , update using PreparedStatement)
  • watchOS WCSession'已配对'和'watchAppAvailable'不可用(watchOS WCSession 'paired' and 'watchAppAvailable' are unavailable)
  • CalledFromWrongThreadException在Android上执行JUnit测试(CalledFromWrongThreadException exercising JUnit tests on Android)
  • 如何把文件保存到你的应用程序目录中?(How to put\save files into your application directory? (adobe air))
  • 美元符号在Java方法描述符中的含义?(Meanings of dollar sign in Java method descriptor?)
  • font-size的含义是什么:1em / 2em?(What doe the meaning of font-size:1em/2em?)
  • h2元素推动其他h2和div。(h2 element pushing other h2 and div down. two divs, two headers, and they're wrapped within a parent div)
  • 创建一个功能(Create a function)
  • Android - 检测与特定wifi ssid断开连接的正确方法?(Android - Correct way to detect disconnecting from a particular wifi ssid?)
  • 通过Shell脚本将文件转换为另一个文件(Convert File To Another File By Shell Script)
  • 我投了份简历,是电脑编程方面的学徒,面试时说要培训三个月,前面
  • 如何过滤magento废弃的购物车报告集合(How to Filter the magento abandoned cart report collection)
  • PDO语句不显示获取的结果(PDOstatement not displaying fetched results)
  • web api http post传递对象504接收失败(web api http post passing object 504 Receive Failure)
  • Rails从视图编辑模型上的多个属性的方法(Rails way to edit multiple attributes on a model from a view)
  • 总是用{}初始化对象是否是好习惯?(Is it good habit to always initialize objects with {}?)
  • 在方案中编写特殊字符到输出端口(编译器设计)(writing special characters to output port in scheme (compiler design))
  • 电脑等级考试得证有多大用处?
  • Qt冻结循环的原因?(Qt freezing cause of the loop?)
  • 第一次调用函数将无法按预期工作,但下一次工作正常(calling a function on the first time won't work as expected, but next time is working)
  • 如何优化使用BigInteger操作执行时间的代码(How to optimize the code that uses BigInteger operations for execution time)
  • TableView重复youtube-api结果(TableView Repeating youtube-api result)
  • 如何提供个人资料信息,以便Passport.js可以使用它?(how does Profile information should be provided so Passport.js can use it?)
  • 有没有办法初始化jquery数据表中的细节?(is there any way to initialize details in jquery datatable?)