0

Basically I have some code for which it will find the equation of a plane and then attempt to place a 1 in a list if a point satisfies this equation of a line, otherwise a 0 is put in for the list. Unfortunately, there has to be an increment amount, so how would you get a point that is closest to the equation so that an approximate plane can be made without a bunch of empty spaces?

Here is the code so far:

def plane(self):
    p1 = self.first_pos
    p2 = self.second_pos
    p3 = self.third_pos
    x1,y1,z1 = self.fourth_pos
    x2,y2,z2 = self.fifth_pos
    a = (p2[0] - p1[0],p2[1] - p1[1],p2[2] - p1[2])
    b = (p3[0] - p1[0],p3[1] - p1[1],p3[2] - p1[2])
    abc = ((a[1] * b[2]) - (a[2] * b[1]),(a[2] * b[0]) - (a[0] * b[2]), (a[0] * b[1]) - (a[1] * b[0]))
    constant = (p1[0] *abc[0] * -1) - (p1[1] * abc[1]) - (p1[2] * abc[2])
    lx = []
    lxy = []
    axyz = []
    if x1 > x2 : x1, x2 = x2, x1
    if y1 > y2 : y1, y2 = y2, y1
    if z1 > z2 : z1, z2 = z2, z1
    for z in range(z1, z2+1):
        for y in range(y1,y2+1):
            for x in range(x1,x2+1):
                if int(round(((abc[1] *y) + (abc[2] *z) + constant + 0.6 ) / (-1 * abc[0]))) == x:
                    lx.append(1)
                else:
                    lx.append(0)
                if x == x2:
                    lxy.append(lx)
                    lx = []
            if y == y2:
                axyz.append(lxy)
                lxy = []
    self.first_pos = self.fourth_pos
    self.second_pos = self.fifth_pos
    self.buildMatrix(axyz)
    self.BuildCuboid(axyz)

Here is an example code for drawing a line that works with the closest points to the actual line being used:

def DrawLine(self):
    self.bot.sendMessage("Drawing line.",ignorable=True)
    fp = self.first_pos
    sp = self.second_pos
    ## This is the vector from pt 1 to pt 2
    x,y,z = sp[0] - fp[0], sp[1] - fp[1], sp[2] - fp[2]

    ## magnitude of that vector
    dist = self.bot.dist3d(fp[0], fp[1], fp[2], sp[0], sp[1], sp[2] )

    ## unit vector
    n_x, n_y, n_z = x/dist, y/dist, z/dist

    ## stepping a dist of 1 in the direction of the unit vector, find the
    ## whole coordinate and place a block at that location
    coords = []
    for d in xrange(0, int(dist)):
        self.blocks.append( (
                       self.block_type,
                       int(round(fp[0] + (n_x * d))),
                       int(round(fp[1] + (n_y * d))),
                       int(round(fp[2] + (n_z * d)))
                       ) )
    self.DrawBlocks()
joseph
  • 1,021
  • 2
  • 9
  • 11
  • Its not really clear if this is a programming question or a math question -- and regardless, there is a lot of code here but not a lot of context. I'm not sure we can help you without more information. – jedwards Nov 05 '11 at 23:47
  • The question is, how can the resulting list end up with a surface that is as close as possible to the actual plane because right now, if the plane isn't horizontal, vertical or the relation between two axes is 1, there won't be a surface but instead a scatter of 1's with 0's in between them. – joseph Nov 05 '11 at 23:54

2 Answers2

0

If I'm understanding your intent correctly, you have a plane defined by three points (p0, p1, p2) and then want to evaluate whether some other point lies in that plane (or very nearly so).

This is most easily expressed using matrices rather than by manipulating the individual coordinate components in the code snippet listed above. Here's a link showing how to use matrices to solve this and related problems: http://paulbourke.net/geometry/planeeq/ .

It looks like your code is already close to representing the equation of the plane (you can verify it by substituting in the original points to see if it evaluates to zero or near zero).

Next, substitute the candidate point to see whether it evaluates to zero or near zero.

Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
  • My intent is to draw a plane in a game of blocks between the two coordinates, the first three coordinates help define the plane, while the last two coordinates define the space in which the plane will be drawn. Right now, if the plane isn't horizontal, vertical or have a relation of 1 between two variables, there is a scatter of points that are exactly on the plane but I want to have something where the plane can be drawn as best as possible with the closest point to the plane being used as well as exact points. – joseph Nov 06 '11 at 00:13
  • I did try to do something to see if it is near zero, like if the answer is <1 and >-1 or something like that, but it still didn't work. – joseph Nov 06 '11 at 00:41
  • How about I give an example using a line: say I have an equation of a line y = 2x from 0 to 4, I would end up with a line if drawn on a graph like this: [00100][00000][01000][00000][10000]. Stack the matrices as seen here to see what I mean as this is supposed to be a visual representation of what happens. What i really want is something like this: [00100][01000][01000][10000][10000]. Or something along the lines of being able to get a connected line. – joseph Nov 06 '11 at 00:53
0

Your problem is a 3-dimensional version of the 2-dimensional line-plotting done by Bresenham's Algorithm. B-A plots a line using cells in a grid, including connecting cells so that you get a continuous line. That is, instead of just indexing column by column and computing the proper cell for the equivalent x-value (which would leave spaces between points if the line is not exactly vertical, horizontal, or 45degrees), B-A moves from cell to cell, determining which adjacent cell is best to fit to the linear equation being plotted.

Adapting this to 3-dimensions might be done by plotting each linear slice in x, and then again for each slice in y. Implementation left as an exercise for the OP. The Wikipedia page includes some links for n-dimensional treatments.

PaulMcG
  • 62,419
  • 16
  • 94
  • 130
  • Thanks for clarifying was the OP actually wanted. The code indicated an effort to determine the proximity of a point to a plane defined by three points. The overall objective was unclear. – Raymond Hettinger Nov 06 '11 at 20:01
  • I'm still guessing. Probably should put a big **"I THINK"** in front of my answer. – PaulMcG Nov 06 '11 at 21:08