joyhughes / Jen

Image processing, generative photography, cellular automata
https://discord.gg/GQQHUbkf
20 stars 20 forks source link

Kaleidoscope warp field #121

Closed joyhughes closed 1 month ago

joyhughes commented 1 month ago

Create a kaleidoscope function which can be used as a warp field.

Start by calculating a vector field and then generating a warp field from that.

Convert to radial coordinates and repeat a wedge n times - allow change in n through a harness.

Option to allow alternate wedges to be reflected.

DM-netizen commented 1 month ago

Hi @joyhughes , I am eager to contribute to your app. I want to work on this issue. I have the knowledge of C++ only, do I need to learn anything else for tackling this issue?

joyhughes commented 1 month ago

C++ is the only language you will need for this task. I am setting up the first part for you right now and making a branch for us to work in. I will work with you but when we are done you will submit the PR.

You will need to know a little math - two dimensional vectors.

I will create the branch and a place for you to work and add to comments.

joyhughes commented 1 month ago

Look at the file https://github.com/joyhughes/Jen/blob/add-kaleidoscope/Lux/src/vector_field.cpp

You will see where I made the changes (a kaleidoscope function)

See if you can follow along:

void vf_tools::kaleidoscope(    const vec2f& center = { 0.0f, 0.0f }, 
                                float segments = 6.0,                // Number of segments in kaleidoscope
                                bool reflect = true ) {              // Reflect alternate segments
    if( segments != 0.0f ) {
        position_fill();
        radial();
        if( reflect ) { for( auto& v : img.base ) { v.y = rmodf( v.y, TAU / segments ) }; }
        else          { for( auto& v : img.base ) { v.y = tmodf( v.y, TAU / segments ) }; }
        cartesian();
    }
}

The pixels are stored in the array img.base. In this case the image is a vector field - each pixel is a vec2f position_fill() gets a coordinate for each pixel radial() switches to radial coordinates then run a modulo function over the y coordinate which is equivalent now to theta switch back to Cartesian coordinates

This should make the kaleidoscope. Next I will show you how to make the warp field.

DM-netizen commented 1 month ago

I get itπŸ‘. Will try my best to solve this

DM-netizen commented 1 month ago

Can you give me some sources to learn the necessary math for creating the function?

joyhughes commented 1 month ago

@DM-netizen

I think the function should work to make a kaleidoscope (maybe it will need to be debugged). But there are other steps - we need to make an effect in order to generate the vector field within the scene (look at effect.hpp). An effect is a functor - are you familiar with functors? They are classes which have the operator () overloaded - look at https://www.geeksforgeeks.org/functors-in-cpp/ and https://stackoverflow.com/questions/356950/what-are-c-functors-and-their-uses

When you understand functors I will teach you how to make a harness, which lets you change the members of one functor class using another functor.

I will show you how to do each step and then you can practice making your own effects. We can make new effects all summer long - lots of PRs! Even though I am doing some of the work this time to demonstrate to you, if you understand you will still get all the points.

joyhughes commented 1 month ago

Watch the Lux Vitae video https://www.youtube.com/watch?v=vN1ApdESIrc @DM-netizen

joyhughes commented 1 month ago

You are correct that we can use code declared in warp_field.hpp to make a warp field from a vector field.

template<> void warp_field::fill( const image< vec2f >& vfield, const bool relative, const image_extend extend );

But first we need to make an effect that calculates the kaleidoscope vector field.

Are you familiar with templates?

DM-netizen commented 1 month ago

I know about templates. I had learnt about what are functors and harness while reading the README.

@DM-netizen

I think the function should work to make a kaleidoscope (maybe it will need to be debugged). But there are other steps - we need to make an effect in order to generate the vector field within the scene (look at effect.hpp). An effect is a functor - are you familiar with functors? They are classes which have the operator () overloaded - look at https://www.geeksforgeeks.org/functors-in-cpp/ and https://stackoverflow.com/questions/356950/what-are-c-functors-and-their-uses

When you understand functors I will teach you how to make a harness, which lets you change the members of one functor class using another functor.

I will show you how to do each step and then you can practice making your own effects. We can make new effects all summer long - lots of PRs! Even though I am doing some of the work this time to demonstrate to you, if you understand you will still get all the points.

I will be happy to contribute more!

joyhughes commented 1 month ago

Okay good I wrote a declaration for the kaleidoscope effect in effect.hpp. Maybe you can write the operator() definition.

template< class T > struct eff_kaleidoscope {
    harness< vec2f > center;
    harness< float > segments;
    harness< float > offset_angle;
    harness< bool >  reflect;

    bool filled;

    void operator () ( any_buffer_pair_ptr& buf, element_context& context );

    eff_kaleidoscope( vec2f center_init = vec2f( 0.0f, 0.0f ), float segments_init = 6.0f, float offset_angle_init = 0.0f, bool reflect_init = true ) : 
        center( center_init ), segments( segments_init ), offset_angle( offset_angle_init ), reflect( reflect_init ), filled( false ) {}
};

typedef eff_kaleidoscope< vec2f > eff_kaleidoscope_vec2f;
DM-netizen commented 1 month ago

Join the Lux Vitae discord channel https://discord.gg/EmmfUEeA @DM-netizen

It's telling the link is invalid or has expired

joyhughes commented 1 month ago

Join the Lux Vitae discord channel https://discord.gg/EmmfUEeA @DM-netizen

It's telling the link is invalid or has expired

Yes sorry that link turned out to be bad. I think I still have to wait for them to open the channel on GSSoC discord.

https://www.youtube.com/watch?v=vN1ApdESIrc should work for the video though

joyhughes commented 1 month ago

Do you know about variants?

DM-netizen commented 1 month ago

Do you know about variants?

No

joyhughes commented 1 month ago

A variant is a modern way to do a union. I use variants in Lux Vitae, so it's good for you to know a little bit about them even if you won't be using them directly. Here is a good intro:

https://www.geeksforgeeks.org/std-variant-in-cpp-17/

Please ask me if you have any questions about variants.

joyhughes commented 1 month ago

to write the operator() definition look in effect.cpp to see how the other effects do it, and put the definition in that file

To update the value of a harness use operator() with the context (example: center( context ) ) - update these first.

It should only run the kaleidoscope function the first time or if one of the harnesses have changed. So check to see if they've changed and set filled to false if they have.

Then run kaleidoscope function on vector field. The vector field is an image of vectors. Since the app sometimes uses double buffering, each image is stored in a buffer pair. any_buffer_pair_ptr is a variant of different types of buffer pairs.

To make it easy to resolve for you I added a function get_image which will take any_buffer_pair_ptr as an argument. It returns a reference to an image of type T. Call it like this:

vftools tools( get_image< T >( buf ) );
tools.kaleidoscope( 

Then for arguments use the value of each harness. To get the value of a harness use the operator (example: `center` )

Once that is done, I can show you how to make a warp field from your vector field, and then we can make a scene to test it.

joyhughes commented 1 month ago

The branch should be ready for you to work in now

joyhughes commented 1 month ago

@DM-netizen please commit your function to this branch. If you are having trouble let me know. Then we can test and I will let you make the pull request. I will handle the merge. This is a level 3 issue and you deserve the points because you are learning so much!

I am making the scene file for testing now.

DM-netizen commented 1 month ago

How can I directly commit to your branch? I tried by git remote set-url origin https://github.com/joyhughes/Jen.git and then git push -u origin add-kaleidoscope but it didn't work. It's giving this error message:

remote: Permission to joyhughes/Jen.git denied to DM-netizen.
fatal: unable to access 'https://github.com/joyhughes/Jen.git/': The requested URL returned error: 403
rudi-cilibrasi commented 1 month ago

should be using ssh: uri

DM-netizen commented 1 month ago

@rudi-cilibrasi Can you tell me the git command as I haven't use ssh before?

rudi-cilibrasi commented 1 month ago

don't use https uri for git repo use git@github.com:joyhughes/Jen.git

that is the uri you need to use in order to push your stuff

DM-netizen commented 1 month ago
PS C:\Users\user\OneDrive\Documents\Github\Jen> git remote -v
origin  git@github.com:joyhughes/Jen.git (fetch)
origin  git@github.com:joyhughes/Jen.git (push)
PS C:\Users\user\OneDrive\Documents\Github\Jen> git push origin add-kaleidoscope
ssh: Could not resolve hostname github.com: Name or service not known
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

This is what I am getting.

rudi-cilibrasi commented 1 month ago

please run this once to fix it then try the push again

ssh -T git@github.com
DM-netizen commented 1 month ago
PS C:\Users\user\OneDrive\Documents\Github\Jen> ssh -T git@github.com
git@github.com: Permission denied (publickey).

I think I don't have the access to do it directly. Should I create a PR?

joyhughes commented 1 month ago
PS C:\Users\user\OneDrive\Documents\Github\Jen> ssh -T git@github.com
git@github.com: Permission denied (publickey).

I think I don't have the access to do it directly. Should I create a PR?

I am setting up proper access for you. Please stand by.

joyhughes commented 1 month ago

@DM-netizen I have merged changes from the kaleidoscope branch into main. You can fork current main and add your function, make a PR, and I can help you test the changes.

You can see the new scene file that we will be using to test. I will walk you through each step of how the test works.

DM-netizen commented 1 month ago

Ok Should I make a PR or follow the test process first?

joyhughes commented 1 month ago

Ok Should I make a PR or follow the test process first?

Make the PR first and we will test out of the PR and make changes to it as necessary

joyhughes commented 1 month ago

@DM-netizen Did that work out for you?

DM-netizen commented 1 month ago

I was a bit busy so I will do the required stuff now. Will let you know if I face any difficulty.

DM-netizen commented 1 month ago

I successfully made my first PR! Thanks for making this easier for me by helping. I am ready to follow the working of the tests now.

joyhughes commented 1 month ago

I am still testing. I found a bug in the renderer that I need to fix before I can complete the tests.

DM-netizen commented 1 month ago

Okk πŸ‘

joyhughes commented 1 month ago

Please join the Lux Vitae discord at https://discord.gg/GQQHUbkf