Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Exit

- Home
- After Effects
- Discussions
- Recursive expression with sampleimage

- Recursive expression with sampleimage

1

Recursive expression with sampleimage

/t5/after-effects-discussions/recursive-expression-with-sampleimage/td-p/14184343
Oct 25, 2023
Oct 25, 2023

Copy link to clipboard

Copied

Hi

I have a project were I try to put one layer (dot) on another layer (circle) with an expression. My plan was to

1. Find a random position for the dot layer.

2. Check if that position is on top of the circle layer, using sampleImage.

3. If it isn't, run a recursive call of the function.

It doesn't seem to work. I'm almost sure the expression is correct, but AE keep crashing. As if I had made an endless loop recursive call. Of course I could be missing something.

The expression looks like this:

```
function findPointOnLayer(targetLayer, functionSeed)
{
seedRandom(functionSeed, true);
var rndX = Math.random();
var rndY = Math.random();
var posX = thisComp.width * rndX;
var posY = thisComp.height * rndY;
var p = [posX, posY];
var sample = targetLayer.sampleImage(p, [0.5, 0.5]);
var sampleAlpha = sample[3];
if( sampleAlpha < 0.2 )
{
p = findPointOnLayer(targetLayer, functionSeed+1);
}
return p;
}
var circleLayer = thisComp.layer("circle");
var seed = effect("seed")("Slider");
findPointOnLayer(circleLayer, seed);
```

To trouble shoot. I have tried the expression below, which will likewise check if the dot layers is postioned on top of the circle layer. If it isn't, instead of the recursive call, it will set p to [0,0]. That works.

```
function findPointOnLayer(targetLayer, functionSeed)
{
seedRandom(functionSeed, true);
var rndX = Math.random();
var rndY = Math.random();
var posX = thisComp.width * rndX;
var posY = thisComp.height * rndY;
var p = [posX, posY];
var sample = targetLayer.sampleImage(p, [0.5, 0.5]);
var sampleAlpha = sample[3];
if( sampleAlpha < 0.2 )
{
p = [0, 0];
}
return p;
}
var circleLayer = thisComp.layer("circle");
var seed = effect("seed")("Slider");
findPointOnLayer(circleLayer, seed);
```

Sample project is attached. Any help is much appreciated.

- Jakob

TOPICS

Expressions

Community guidelines

Be kind and respectful, give credit to the original source of content, and search for duplicates before posting.
Learn more

8
Replies
8

/t5/after-effects-discussions/recursive-expression-with-sampleimage/m-p/14184489#M238625
Oct 25, 2023
Oct 25, 2023

Copy link to clipboard

Copied

That's probably not going to work conceptually as you are re-seeding the random function inside the main loop. That way you may never actually get a hit because in your case you're actually changing it whenever there would be a hit so it moves away to the next sample. It would probably work better if you separated the functions and controlled the main loop with break and continue statements based on whether the hit is true or false.

Mylenium

Community guidelines

Be kind and respectful, give credit to the original source of content, and search for duplicates before posting.
Learn more

Jakob Wagner 2048
AUTHOR

Engaged
,

/t5/after-effects-discussions/recursive-expression-with-sampleimage/m-p/14184507#M238627
Oct 25, 2023
Oct 25, 2023

Copy link to clipboard

Copied

Thanks for the reply. But actually, I do take that into account by adding 1 to the seed for every recursion.

`p = findPointOnLayer(targetLayer, functionSeed+1);`

It's a good idea to try a while loop instead, but I still don't see why the recursion call doesn't work.

Community guidelines

Be kind and respectful, give credit to the original source of content, and search for duplicates before posting.
Learn more

Jakob Wagner 2048
AUTHOR

Engaged
,

/t5/after-effects-discussions/recursive-expression-with-sampleimage/m-p/14184569#M238629
Oct 25, 2023
Oct 25, 2023

Copy link to clipboard

Copied

I have just tried to do this with a while loop. Which may be a simpler way to do it. But the problem seems to be the same. It will go into an endless loop, freezing AE.

```
var circleLayer = thisComp.layer("circle");
var seed = effect("seed")("Slider");
var sampleAlpha = 0;
var p = [0, 0];
while (sampleAlpha<=0.2)
{
seedRandom(seed, true);
var rndX = Math.random();
var rndY = Math.random();
var posX = thisComp.width * rndX;
var posY = thisComp.height * rndY;
p = [posX, posY];
var sample = circleLayer.sampleImage(p, [0.5, 0.5]);
sampleAlpha = sample[3];
seed++;
}
p;
```

While the below does not go into endless loop but obvoiusly doesn't do anything but to leave the loop.

```
var circleLayer = thisComp.layer("circle");
var seed = effect("seed")("Slider");
var sampleAlpha = 0;
var p = [0, 0];
while (sampleAlpha<=0.2)
{
seedRandom(seed, true);
var rndX = Math.random();
var rndY = Math.random();
var posX = thisComp.width * rndX;
var posY = thisComp.height * rndY;
p = [posX, posY];
var sample = circleLayer.sampleImage(p, [0.5, 0.5]);
sampleAlpha = 1;
seed++;
}
p;
```

There must be somthing wrong with the sampleImage output. Although, I have tested it and it does return 1 as it should?

Community guidelines

/t5/after-effects-discussions/recursive-expression-with-sampleimage/m-p/14184938#M238643
Oct 25, 2023
Oct 25, 2023

Copy link to clipboard

Copied

Depending on what your objective is, I'd be tempted to do something like this, ditching sampleImage and recursion:

```
circle = thisComp.layer("circle");
radius = circle.width/2 - width/2;
seedRandom(index,true);
r = random(radius);
a = random(Math.PI*2);
x = r*Math.sin(a);
y = r*Math.cos(a);
circle.position + [x,y]
```

Community guidelines

Jakob Wagner 2048
AUTHOR

Engaged
,

/t5/after-effects-discussions/recursive-expression-with-sampleimage/m-p/14186629#M238659
Oct 26, 2023
Oct 26, 2023

Copy link to clipboard

Copied

Community guidelines

/t5/after-effects-discussions/recursive-expression-with-sampleimage/m-p/14184895#M238639
Oct 25, 2023
Oct 25, 2023

Copy link to clipboard

Copied

Again, I think changing the seed inside the loop probably causes mayhem. Even just incrementing it by 1 may produce insanely large numbers and exhaust the internal cycles. Also a thought that occured to me after my first reply: A one pixel hit area may be to small and you may need an additional loop to progressively refine the check - test a 50 x 50 area first and then go smaller iteratively until you find the exact hit point. Point being that never finding anything may also simply exhaust all cycles.

Mylenium

Community guidelines

Jakob Wagner 2048
AUTHOR

Engaged
,

/t5/after-effects-discussions/recursive-expression-with-sampleimage/m-p/14184923#M238642
Oct 25, 2023
Oct 25, 2023

Copy link to clipboard

Copied

Thank you for answering, but I don't think you're right about any of that.

The sampleImage seems to work when tested with same random values and return 1 in the alpha as it should. Even with a one pixel hit area.

The layer that is being targeted is taking up more than half of the space in the comp and is easially hit. Again, I tested it with the exact random point, and it is a hit.

Community guidelines

Jakob Wagner 2048
AUTHOR

Engaged
,

LATEST
/t5/after-effects-discussions/recursive-expression-with-sampleimage/m-p/14186672#M238660
Oct 26, 2023
Oct 26, 2023

Copy link to clipboard

Copied

I found a solution. But I don't understand this. The following will break AE:

```
var circleLayer = thisComp.layer("circle");
var seed = effect("seed")("Slider");
var sampleAlpha = 0;
var p = [0, 0];
while (sampleAlpha<0.2)
{
seedRandom(seed, true);
var rndX = Math.random();
var rndY = Math.random();
var posX = thisComp.width * rndX;
var posY = thisComp.height * rndY;
p = [posX, posY];
var sample = circleLayer.sampleImage(p, [0.5, 0.5]);
sampleAlpha = sample[3];
seed++;
}
p;
```

However, the following will work. Which i don't understand because that means the sampleAlpha must change to something higher than 0.2. So if it does, why doesn't the above while statement exit loop?

```
var circleLayer = thisComp.layer("circle");
var seed = effect("seed")("Slider");
var sampleAlpha = 0;
var p = [0, 0];
var i = 0;
while (i<100)
{
seedRandom(seed, true);
var rndX = Math.random();
var rndY = Math.random();
var posX = thisComp.width * rndX;
var posY = thisComp.height * rndY;
p = [posX, posY];
var sample = circleLayer.sampleImage(p, [0.5, 0.5]);
sampleAlpha = sample[3];
if(sampleAlpha>0.2)
{
break;
}
i++;
seed++;
}
p;
```

Weirdly, the following will also break AE. Shouldn't it simply "break" like the working example above? (note true in while statement)

```
var circleLayer = thisComp.layer("circle");
var seed = effect("seed")("Slider");
var sampleAlpha = 0;
var p = [0, 0];
var i = 0;
while (true)
{
seedRandom(seed, true);
var rndX = Math.random();
var rndY = Math.random();
var posX = thisComp.width * rndX;
var posY = thisComp.height * rndY;
p = [posX, posY];
var sample = circleLayer.sampleImage(p, [0.5, 0.5]);
sampleAlpha = sample[3];
if(sampleAlpha>0.2)
{
break;
}
i++;
seed++;
}
p;
```

Any clearifications is very appreciated.

- Jakob

Community guidelines

Resources

Troubleshooting FAQs

After Effects Community Recap

Getting started with After Effects

Copyright © 2024 Adobe. All rights reserved.