coordinates for next internal square

Hi, the next question :)

Imagine big square and several small squares inside it. These small squares should appear automatically and should not lay one over other. So, the problem is to calculate next X and next Y for each new square to be placed on big square. I need a proper algorythm to do that.

Please advice.

Thanks and regards,

F.

[368 byte] By [firebunnya] at [2007-11-26 16:18:56]
# 1

import java.awt.*;

import java.awt.event.*;

import java.util.*;

import java.util.List;

import javax.swing.*;

import javax.swing.event.MouseInputAdapter;

public class MSFRx extends JPanel {

Rectangle crib;

List<Rectangle> rects;

int[] limits;

final int S = 25;

final int PAD = 3;

final int MARGIN = 40;

public MSFRx() {

Dimension d = getPreferredSize();

crib = new Rectangle(MARGIN, MARGIN, d.width-2*MARGIN, d.height-2*MARGIN);

rects = new ArrayList<Rectangle>();

initLimits();

}

protected void paintComponent(Graphics g) {

super.paintComponent(g);

Graphics2D g2 = (Graphics2D)g;

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

g2.setPaint(Color.green.darker());

g2.draw(crib);

g2.setPaint(Color.blue);

for(Rectangle r : rects)

g2.draw(r);

}

public void setRect(Rectangle r, int x, int y) {

r.setLocation(x, y);

repaint();

}

public void addRect() {

int x = (int)(crib.getCenterX() - S/2.0);

int y = crib.y + 1;

Rectangle r = new Rectangle(x, y, S, S);

Point nextPos = getNextPosition(r);

if(nextPos != null) {

r.setLocation(nextPos);

rects.add(r);

}

repaint();

}

private Point getNextPosition(Rectangle r) {

int w = crib.width;

int h = crib.height;

int xPos = crib.x + w/2, yPos = crib.y + 1;

for(int j = 0; j < rects.size()+1; j++) {

if(j < limits[0]) {

xPos = crib.x + w/2 + j*(S + PAD);

yPos = crib.y + 1;

} else if(j < limits[1]) {

xPos = crib.x + w - S -1;

yPos = crib.y + 1 + (j + 1 - limits[0])*(S + PAD);

} else if(j < limits[2]) {

xPos = crib.x + w - (j + 2 - limits[1])*(S + PAD);

yPos = crib.y + h - S - 1;

} else if(j < limits[3]) {

xPos = crib.x + 1;

yPos = crib.y + h - (j + 2 - limits[2])*(S + PAD);

} else if(j < limits[4]) {

xPos = crib.x + 1 + (j + 1 - limits[3])*(S + PAD);

yPos = crib.y + 1;

} else {

System.out.println("crib is full");

return null;

}

}

return new Point(xPos, yPos);

}

public Dimension getPreferredSize() {

return new Dimension(400,400);

}

private void initLimits() {

int w = crib.width;

int h = crib.height;

int[] numRects = new int[5];

// top middle to top right corner

numRects[0] = (w/2)/(S + PAD);

// right side: top to bottom

numRects[1] = (h - S - PAD)/(S + PAD);

// bottom: right to left

numRects[2] = (w - S - PAD)/(S + PAD);

// left: bottom to top

numRects[3] = (h - S + PAD)/(S + PAD);

// top: left corner to middle

numRects[4] = (w/2 - S - PAD - 1)/(S + PAD);

limits = new int[numRects.length];

for(int j = 0, total = 0; j < limits.length; j++) {

total += numRects[j];

limits[j] = total;

}

//System.out.printf("numRects = %s%nlimits = %s%n",

//Arrays.toString(numRects), Arrays.toString(limits));

}

public static void main(String[] args) {

MSFRx test = new MSFRx();

RectangleWrangler rw = new RectangleWrangler(test);

test.addMouseListener(rw);

test.addMouseMotionListener(rw);

JFrame f = new JFrame("Click in green to add rectangles");

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.getContentPane().add(test);

f.pack();

f.setLocationRelativeTo(null);

f.setVisible(true);

}

}

class RectangleWrangler extends MouseInputAdapter {

MSFRx component;

Rectangle selectedRect = null;

Point offset = new Point();

boolean dragging = false;

public RectangleWrangler(MSFRx msfrx) {

component = msfrx;

}

public void mousePressed(MouseEvent e) {

Point p = e.getPoint();

List<Rectangle> list = component.rects;

// Are we selecting an existing rectangle?

for(int j = 0; j < list.size(); j++) {

Rectangle r = list.get(j);

if(r.contains(p)) {

selectedRect = r;

offset.x = p.x - r.x;

offset.y = p.y - r.y;

dragging = true;

break;

}

}

// Or are we adding a new rectangle to the crib?

if(selectedRect == null && component.crib.contains(p))

component.addRect();

}

public void mouseReleased(MouseEvent e) {

dragging = false;

selectedRect = null;

}

public void mouseDragged(MouseEvent e) {

if(dragging) {

Point p = e.getPoint();

double cx = selectedRect.getCenterX();

double cy = selectedRect.getCenterY();

Rectangle crib = component.crib;

int S = component.S;

boolean top= cy - crib.y < S;

boolean left= cx - crib.x < S;

boolean bottom = crib.y + crib.height - cy < S;

boolean right = crib.x + crib.width - cx < S;

boolean horizontal = top || bottom;

boolean vertical= left || right;

if(horizontal && vertical) {

if(top && left) {

// Check boundries.

if(selectedRect.x - crib.x < 0) selectedRect.x = crib.x -1;

if(selectedRect.y - crib.y < 0) selectedRect.y = crib.y +1;

// Choose direction according to larger displacment.

if(Math.abs(p.x - offset.x) <= Math.abs(p.y - offset.y))

horizontal = false;

else

vertical = false;

} else if(left && bottom) {

if(selectedRect.x - crib.x < 0) selectedRect.x = crib.x +1;

if(crib.y + crib.height - selectedRect.y < S)

selectedRect.y = crib.y + crib.height - S -1;

if(Math.abs(p.x - crib.x) < Math.abs(p.y - crib.y - crib.height))

horizontal = false;

else

vertical = false;

} else if(bottom && right) {

if(crib.x + crib.width - selectedRect.x + S < 0)

selectedRect.x = crib.x + crib.width - S -1;

if(crib.y + crib.height - selectedRect.y + S < 0)

selectedRect.y = crib.y + crib.height - S -1;

if(Math.abs(p.x - crib.x - crib.width) <=

Math.abs(p.y - crib.y - crib.height))

horizontal = false;

else

vertical = false;

} else if(right && top) {

if(crib.x + crib.width - selectedRect.x + S < 0)

selectedRect.x = crib.x + crib.width - S -1;

if(selectedRect.y - crib.y < 0) selectedRect.y = crib.y +1;

if(Math.abs(p.x - crib.x - crib.width) <= Math.abs(p.y - crib.y))

horizontal = false;

else

vertical = false;

}

}

int x = p.x - offset.x;

int y = p.y - offset.y;

// Make the rectangle follow the line.

if(horizontal) {

if(top) {

y = crib.x + 1;

} else if(bottom) {

y = crib.y + crib.height - S -1;

}

} else if(vertical) {

if(left) {

x = crib.x + 1;

} else if(right) {

x = crib.x + crib.width - S -1;

}

}

component.setRect(selectedRect, x, y);

}

}

}

crwooda at 2007-7-8 22:42:15 > top of Java-index,Security,Cryptography...