Hi: The function below plots the line segment between two points A and B as well as the normal from C to AB, with a dot as the intersection point (D), which is returned with the function call. The aspect ratio is kept at one so that the orthogonality between the two lines is not distorted by the axis scaling.
The input is a 3 x 2 matrix with point A in the first row, B in the second and C in the third. normalLine <- function(pts) { # A function that takes points A, B, C (rows of matrix pts) # as input # find slope of line between A and B # find equation of normal that passes through C # find the intersection point D between AB and its normal # through C if(nrow(pts) != 3 || ncol(pts) != 2) stop('input matrix must be 3 x 2') A <- pts[1, , drop = TRUE] B <- pts[2, , drop = TRUE] C <- pts[3, , drop = TRUE] slopeAB <- (B[2] - A[2])/(B[1] - A[1]) slopeNorm <- -1/slopeAB a <- A[2] - slopeAB * A[1] b <- C[2] - slopeNorm * C[1] xintersect <- (b - a)/(slopeAB - slopeNorm) yintersect <- b + slopeNorm * xintersect mxlim <- max(pts) mnlim <- min(pts) plot(pts[, 1], pts[, 2], pch = c('A', 'B', 'C'), xlab = "", ylab = "", xlim = c(mnlim, mxlim), ylim = c(mnlim, mxlim)) segments(A[1], A[2], B[1], B[2]) segments(xintersect, yintersect, C[1], C[2]) points(xintersect, yintersect, pch = 16, cex = 1.2) c(xintersect, yintersect) } ## Test: pts <- matrix(c(1, 2, 5, 9, 3, 4), ncol = 2, byrow = TRUE) normalLine(pts) HTH, Dennis On Wed, Aug 25, 2010 at 8:54 AM, William Revelle <li...@revelle.net> wrote: > At 3:04 PM -0700 8/23/10, CZ wrote: > >> Hi, >> >> I am trying to draw a perpendicular line from a point to two points. >> Mathematically I know how to do it, but to program it, I encounter some >> problem and hope can get help. Thanks. >> >> I have points, A, B and C. I calculate the slope and intercept for line >> drawn between A and B. >> I am trying to check whether I can draw a perpendicular line from C to >> line >> AB and get the x,y value for the point D at the intersection. >> >> Assume I get the slope of the perpendicular line, I will have my point (D) >> using variable x and y which is potentially on line AB. My idea was >> using >> |AC|*|AC| = |AD|*|AD|+ |CD|*|CD|. I don't know what function I may need >> to >> call to calculate the values for point D (uniroot?). >> > > > This is easier than you think. > Think of the x,y coordinates of each point : > Then, the slope is slope = rise/run = (By- Ay)/(Bx- Ax) > The Dx coordinate = Cx and the Dy = (Dx - Ax) * slope > Then, to draw the line segment from C to D > lines(C,D) > > In R: > > A <- c(2,4) > B <- c(4,1) > C <- c(8,10) > slope <-( C[2]- A[2])/(C[1]-A[1]) #rise/run > D <- c(B[1],(B[1]-A[1])*slope + A[2]) # find D > > my.data <- rbind(A,B,C,D) > colnames(my.data) <- c("X","Y") > my.data #show it > plot(my.data,type="n") #graph it without the points > text(my.data,rownames(my.data)) #put the points in > segments(A[1],A[2],C[1],C[2]) #draw the line segments > segments(B[1],B[2],D[1],D[2]) > > Bill > > > > >> Thank you. >> >> >> >> -- >> View this message in context: >> http://r.789695.n4.nabble.com/Draw-a-perpendicular-line-tp2335882p2335882.html >> Sent from the R help mailing list archive at Nabble.com. >> >> ______________________________________________ >> R-help@r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide >> http://www.R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code. >> > > ______________________________________________ > R-help@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. > [[alternative HTML version deleted]] ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.