Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by Tageos · Dec 20, 2015 at 03:17 PM · c#graphiterate

set value to 0 every forth iteration.

Hello!

I am making a graph with a set amount of local (or relative?) maximum/minimum-points. Between these points there are lines containing 3 gameobjects. The maximum/minimum-points are randomly generated between y = 0f,1f. What i am trying to put the 3 gameobjects between the maximum/minimum-points, these 3 objects should follow the equation of a line that is calculated from said maximum/minimum-points.

I have done everything right, but what i cant figure out is how to reset the b value of the lines (y = ax+b).

This is the code with some comments:

 using UnityEngine;
 using System.Collections;
 
 public class perlin : MonoBehaviour {
 
     public GameObject point;
     public GameObject[] points;
     private float x;
     private float y;
     private float a;
     private float b;
 
     void Start () {
 
         //Generetes a straight line of gameobjects
         for (int i = 0; i < points.Length; i++){
 
             x = i;
             points[i] = Instantiate(point,new Vector3 (x*0.25f,y,0),transform.rotation) as GameObject;
         
         }
 
         //Sets the local maximum/minimum-points.
         for (int i = 0; i < points.Length; i+=4){
 
             Vector3 temp = points[i].transform.position;
             temp.y =  Random.Range(0f,1f);
             points[i].transform.position = temp;
 
         }
 
         //Sets the position of the gameobjects between the local maximum/minimum-points.
         for (int i = 0; i < points.Length; i++){
 
             if ((i % 4) == 0 && i < points.Length - 4){ 
                 if (points[i].transform.position.y > points[i+4].transform.position.y){
                 a = -Mathf.Abs((points[i].transform.position.y-points[i+4].transform.position.y)/(points[i].transform.position.x-points[i+4].transform.position.x)); 
                 }
                 if (points[i].transform.position.y < points[i+4].transform.position.y){ 
                 a =  Mathf.Abs((points[i].transform.position.y-points[i+4].transform.position.y)/(points[i].transform.position.x-points[i+4].transform.position.x)); 
                 }
                 b = points[i].transform.position.y; //HOW TO RESET THIS?
             }
         
             if ((i % 4) != 0){ 
 
                 Vector3 temp = points[i].transform.position;
                 temp.y =  a*points[i].transform.position.x+b; 
                 points[i].transform.position = temp;
 
             }
         }
     }
 }

Now, this first line of gameobjects is at its right position but the second, third, forth.... is way out of position since b never resets to 0. If i reset b to 0 every 4th iteration of i (when the index is at a maximum/minimum-point) i think i could achive what i want, my question is how to do this in the code.

A poorly drawn picture of what i am trying to achive: alt text

Any help is appretiated!

Thank you!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by wibble82 · Dec 21, 2015 at 01:58 PM

The issue with your maths is that you calculate a 'gradient' every 4 points, which you call 'a', and also store an offset, 'b'. 'a' is a number that you can plug into the equation:

 y = ax + b

to get a new position.

However, writing it more fully we would write:

 new_y = gradient * change_in_x_since_last_worked_out_gradient + y_when_last_worked_out_gradient

When we look at it that way, we can see why your code doesn't work. On line 48, you simply multiply the current point's x position by a. This works for the first 4 points that have an x between 0 and 1, but after that you're going wrong - for the 10th point you're doing:

 new_y = (10/4)*a + b

However you haven't traveled a distance of 10/4 (or 2.5) since you last calculated a gradient - you've traveled a distance of 0.5.

I had a go at rewriting your logic a bit, in a slightly cleaner way. I've thought of it in terms of 'key frames', so my maths is based around working out how far my current point is from the previous key frame.

     void Start () {
  
          //Generate a line of points at y = 0 (as the variable y defaults to 0 and we don't change it anywhere else)
          for (int i = 0; i < points.Length; i++){
  
              x = i;
              
              //instantiate object at x*0.25, so every 4 points are 1 unit apart
              //note: we use static '(type)' cast, not dynamic 'as' cast, because we EXPECT result to be game object
              points[i] = (GameObject)Instantiate(point,new Vector3 (x*0.25f,y,0),transform.rotation);
          }
  
          //Assign random y between 0 and 1 to every 4th point
          for (int i = 0; i < points.Length; i+=4){
  
              Vector3 temp = points[i].transform.position;
              temp.y =  Random.Range(0f,1f);
              points[i].transform.position = temp;
          }
  
          //Sets the position of the gameobjects between the local maximum/minimum-points 
          //(I would call these keyframes, as that's what they really are in this sense!)
          for (int i = 0; i < points.Length; i++){
  
              //calculate the number of points
              int points_since_keyframe = i%4;
 
              if (points_since_keyframe == 0 && i < points.Length - 4)
              { 
                  //get current and next y
                  float current_y = points[i].transform.position.y;
                  float next_y = points[i+4].transform.position.y;
 
                  //calculate change in y
                  float y_delta = (next_y-current_y);
                  
                  //calculate change in x (note: this is always 1, as we spaced our points 1 unit apart earlier!)
                  //float x_delta = points[i].transform.position.x-points[i+4].transform.position.x; 
                  float x_delta = 1;
 
                  //gradient (a) is dy/dx
                  a = y_delta/x_delta;
 
                  //offset (b) is y position of first point
                  b = points[i].transform.position.y; //HOW TO RESET THIS?
              }
          
              if (points_since_keyframe != 0)
              { 
                  //we need to calculate how far we have moved since a and b were calculated (will be somewhere between 0.25 and 0.75)
                  //I'm pretty sure it'll be the remainder of the points since the key frame / 4, as that would mean that:
                  float x_delta = (float)points_since_keyframe / 4.0f;
                  
                  //now that we know how far we've moved in x since we calculated a and b, we can use y=ax+b to get the new position
                  //proof for start/end points:
                  //  after 0 points, we would have x_delta = 0, so y = 0*a+b = current_y in above logic
                  //  after 4 points (assuming we didn't reset above), we would have x_delta = 1, so y = 1*a+b = next_y in above logic
                  float new_y = x_delta*a + b;
 
                  //now store the new y
                  Vector3 temp = points[i].transform.position;
                  temp.y =  new_y; 
                  points[i].transform.position = temp;
              }
          }
      }

It's untested so might need some compile fixes, but is along the correct lines. Critically:

  • I'm doing almost exactly the same as you (in a slightly simpler way) to recalculate a and b every 4th point

  • However when using a and b, I am using the x distance travelled since the last key frame, not the overall x position

Hope that helps

-Chris

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Tageos · Dec 21, 2015 at 11:01 PM 0
Share

Thank you for the explicit answer Chris! It really helped solve my problem!

avatar image
0

Answer by dhore · Dec 21, 2015 at 05:16 AM

You're already doing other calculations on every fourth iteration of i when you check if ((i % 4) == 0 ... ) So if you want to set b to 0 then just do b = 0; instead of b = points[i].transform.position.y;

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

create graph editior for values 0 Answers

Get comments on Unity using Facebook Graph API 0 Answers

how do i read a node value in shader graph with c # code? 0 Answers

Emulating an X-Y oscilloscope? 1 Answer

,Code in loop simultaneously executing on members of array rather than iterating one at a time 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges