Fitting n shapes of size n x m into a container size n.

Started by bwharrington, August 08, 2019, 07:04:11 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

bwharrington

I have a problem that I do not believe is terribly unique and I wonder if this has been solved and may be laying around out there.

As the title suggests,

1 - I have n shapes in a container
2 - The shapes have a fixed size of 1 x 1 to start.
3 - The  container is size n x m. Any size really.

I need to place all of the size from left to right in a row/column format in order to take up as much of the space as I can. Resizing the shapes to fit. The last row can have a minimum of 1 shape in it.

Has this been solved or possibly a similar solution with some tweaking might get me there? I figure I would spend some time searching rather than reinvent the wheel here.

Thanks,

wapperdude

Visio 2019 Pro

Yacine

Hello bw,The post Wapperdude is referring to is for a real bin stacking problem. Quite challenging for us "simple" visio guys. s. attached sketch of such an exercise.

Your question if I take literally is simple.
n shapes in a container n x m will be placed in exactly one row. (m-1) x n space will remain free.

But, I believe you just formulated the question inaccurately.

You probably meant:
The shapes are squares of side b
The are x shapes
The container's dimensions are n x m

In this case the position of a shape shp_i would be:
shp_i.x = i modulo (m/b) * b
shp_i.y = floor(i / (m/b) ) * b

You may look at the following posts for automation:
- Thomas Winkel: http://visguy.com/vgforum/index.php?topic=4927.0-
- Shapes relations tool: http://visguy.com/vgforum/index.php?topic=6914.15

Yacine

bwharrington

#3
Thanks Yacine,

I apologize for not getting back sooner. I really appreciate the effort you have put into my post and the other post I reviewed of yours for us mortal individuals :).

I've been attempting to tweak what you have provided to more accurately fit my scenario. Your summation of what I need to do its pretty accurate but I posted an image of what I am trying to do.

So far I have taken your idea and put it into code.

What I am finding is the shapes are stacking from left to right, bottom up and in relation to the page instead of the container. I've been trying to manipulate this in such a way that it going from left to right, top down starting in the container with a 3mm margin.

I'm going to continue tinkering with this. One advantage I do have is that the shape size can be reduced or increased as desired.


var shapeWidth = componentStyle == ComponentStyle.Modern ? VisioConstants.MODERN_SHAPE_WIDTH : VisioConstants.CLASSIC_SHAPE_WIDTH;
var shapeHeight = componentStyle == ComponentStyle.Modern ? VisioConstants.MODERN_SHAPE_HEIGHT : VisioConstants.CLASSIC_SHAPE_HEIGHT;

var containerShapeIds = container.ContainerProperties.GetMemberShapes((int)VisContainerFlags.visContainerFlagsDefault);
var sortedDictionary = VisioHelper.CreateAndSortShapeDictionary(_application, containerShapeIds);

decimal containerWidth = (decimal)container.GetMeasuredValue("Width", VisUnitCodes.visInches);
decimal containerHeight = (decimal)container.GetMeasuredValue("Height", VisUnitCodes.visInches);

int i = 0;
foreach (var shape in sortedDictionary)
{
    var shapeX = i % ((double)containerWidth / shapeWidth) * shapeWidth;
    var shapeY = Math.Floor(i / (double)containerWidth / shapeWidth) * shapeWidth;
    var containedShape = _application.ActivePage.Shapes.ItemFromID[shape.Key];
    containedShape.SetPin(shapeX, shapeY);
    i++;
}



Yacine

Your code looks good so far.
It seems the last point left is to invert the vertical order.
Instead of y = floor(i / (m/b) ) * b
you would write y = container.piny - floor(i / (m/b) ) * b

Note that it would simplify your work if set locpiny to height*1 and locpinx to width*0. So you won't have to care about the height and the width when placing the images.

Rgds,
Y.
Yacine

bwharrington

Thanks Yacine,

I think this got me where I needed to be. Your formulas are exactly what I needed to get the ball rolling.

maclarkson

Hay BW, did you programmatically create your own container, this look like something I could use if so?

wapperdude

@ maclarkson:  have you looked at this post, Of Containers and Lists, http://visguy.com/vgforum/index.php?topic=8697.0?

Couple of Visio files and useful links.
Visio 2019 Pro

bwharrington

#8
@maclarkson

I apologize for not seeing this sooner. I did not create my own container. I use the native visio container functionality.