Drawing rectangle between two points with arbitrary width

后端 未结 3 1766
被撕碎了的回忆
被撕碎了的回忆 2020-12-08 17:06

I\'m trying to draw a line between two (2D) points when the user swipes their finger across a touch screen. To do this, I plan on drawing a rectangle on every touch update b

相关标签:
3条回答
  • 2020-12-08 17:24

    If I understand you correctly, you have two end points say A(x1,y1) and B(x2,y2) and an arbitrary width for the rectangle say w. I assume the end points will be just at the middle of the rectangle's shorter sides meaning the distance of the final rectangles corner coordinates would be w/2 to A and B.

    You can compute the slope of the line by;

    s1 = (y2 - y1) / (x2 - x1) // assuming x1 != x2

    The slope of the shorter sides is nothing but s2 = -1/s1.

    We have slope, we have distance and we have the reference points.

    We than can derive two equations for each corner point:

    For one corner closer to A

    C(x3,y3):

    (y3 - y1) / (x3 - x1) = s2 // by slope

    (y3 - y1)^2 + (x3 - x1)^2 = (w/2)^2 // by distance

    replacing (y3 - y1) by a and (x3 - x1) by b yields

    a = b * s2 // slope equation

    // replace a by b*s2

    b^2 * s2^2 + b^2 = (w/2)^2 // distance equaiton

    b^2 = (w/2)^2 / (s2^2+1)

    b = sqrt((w/2)^2 / (s2^2+1))

    we know w and s2 and hence compute b

    If b is known, we can deduce x3

    x3 = b + x1

    and a, as well

    a = b * s2

    and so y3

    y3 = b*s2 + y1

    we have one corner point C(x3,y3).

    To compute the other corner point closer to A, say D(x4,y4), the slope equation can be constructed as

    (y1 - y4) / (x1 - x4) = s2 and the calculations listed above should be applied.

    Other two corners can be calculated with the steps listed here replacing A(x1, y1) with B(x2,y2).

    0 讨论(0)
  • 2020-12-08 17:26

    Calculate a vector between start and end points

    V.X := Point2.X - Point1.X;
    V.Y := Point2.Y - Point1.Y;
    

    Then calculate a perpendicular to it (just swap X and Y coordinates)

    P.X := V.Y; //Use separate variable otherwise you overwrite X coordinate here
    P.Y := -V.X; //Flip the sign of either the X or Y (edit by adam.wulf)
    

    Normalize that perpendicular

    Length = sqrt(P.X * P.X + P.Y * P.Y); //Thats length of perpendicular
    N.X = P.X / Length;
    N.Y = P.Y / Length; //Now N is normalized perpendicular
    

    Calculate 4 points that form a rectangle by adding normalized perpendicular and multiplying it by half of the desired width

    R1.X := Point1.X + N.X * Width / 2;
    R1.Y := Point1.Y + N.Y * Width / 2;
    R2.X := Point1.X - N.X * Width / 2;
    R2.Y := Point1.Y - N.Y * Width / 2;
    R3.X := Point2.X + N.X * Width / 2;
    R3.Y := Point2.Y + N.Y * Width / 2;
    R4.X := Point2.X - N.X * Width / 2;
    R4.Y := Point2.Y - N.Y * Width / 2;
    

    Draw rectangle using these 4 points.

    Here's the picture:

    Drawing rectangle between two points

    EDIT: To answer the comments: If X and Y are the same then the line is exactly diagonal and perpendicular to a diagonal is a diagonal. Normalization is a method of making a length to equal to 1, so that the width of your line in this example will not depend on perpendiculars length (which is equal to lines length here).

    0 讨论(0)
  • 2020-12-08 17:44

    Easy way (I'll call the "width" the thickness of the line):

    We need to calculate 2 values, the shift on the x axis and the shift on the y axis for each of the 4 corners. Which is easy enough.

    The dimensions of the line are:

    width = x2 - x1
    
    height = y2 - y1
    

    Now the x shift (let's call it xS):

    xS = (thickness * height / length of line) / 2
    
    yS = (thickness * width / length of line) / 2
    

    To find the length of the line, use Pythagoras's theorem:

    length = square_root(width * width + height * height)
    

    Now you have the x shift and y shift.

    First coordinate is: (x1 - xS, y1 + yS)
    
    Second: (x1 + xS, y1 - yS)
    
    Third: (x2 + xS, y2 - yS)
    
    Fourth: (x2 - xS, y2 + yS)
    

    And there you go! (Those coordinates are drawn counterclockwise, the default for OpenGL)

    0 讨论(0)
提交回复
热议问题