Subscribe to this thread
Home - General / All posts - Script to draw perendicular line from selected point to selected line
atomek

422 post(s)
#08-Aug-14 16:01

Hi,

Does anyone have or is able to assist in writing a script that will draw a perpendicular line between selected point and selected line? I would like it to work with objects in any layer so this could be used as a tool (like "Offset" script by Tim&Klaus) rather than a dedicated solution.

I imagine it would work like:

1. Find layer which contains selected point & find layer which contains selected line (in currently open map)

2. Extend the line both ways by distance from selected point to selected lines startpoint or endpoint (whatever is further) - that's to let a line be drawn where selected lines length and points location make it impossible drawing a perpendicular line between them without using an extension

3. Copy selected point and snap that copy to nearest location on selected line

4. Draw a line (on points layer) between selected point and its copy

First two steps are out of my skill range :(

Any help appreciated. Thank you.

adaptagis

633 post(s)
#11-Aug-14 15:03

how about good old voroni to start with?

it surely works with the points and it might also work with the lines if you take the endpoints of the lines.

atomek

422 post(s)
#11-Aug-14 19:46

thanks, I didn't even think of using voronoi for that.

Sloots

678 post(s)
#13-Aug-14 08:30

Hi Atomek,

I have written a query that creates perpendicular lines from one or more selected points to one or more selected lines. It uses some algebra to calculate the line(s).

SELECT

 NewLine(

 NewPoint(x3, y3),

 NewPoint(x3 - k * (y2-y1), y3 + k * (x2-x1))

 ) perpendicular

FROM (

 SELECT

 ((y2-y1) * (x3-x1) - (x2-x1) * (y3-y1)) / ((y2-y1)^2 + (x2-x1)^2) k,

 x3,

 y3,

 y2,

 x2,

 y1,

 x1

 FROM

 (

 SELECT

 MinY(StartPoint(L.ID)) y1, 

 MinY(EndPoint(L.ID)) y2,

 MinX(StartPoint(L.ID)) x1,

 MinX(EndPoint(L.ID)) x2,

 MinX((P.ID)) x3,

 MinY((P.ID)) y3

 FROM

 [Line] L,

 [Point] P

 WHERE

 L.[Selection (I)]

 AND

 P.[Selection (I)]

 )

 )

The points are in a drawing called Point and the lines in a drawing named Line.

In the attached map file I've linked this query as a drawing. It works fine unless the line is exactly vertical or horizontal.

(Edit) I expected it to fail in case of horizontal and vertical lines, but after trying it seems to work fine in these cases too! It only fails if the line is of length zero. But then it is a point, not a line.

Cheers,

Chris

Attachments:
perpendicular.map


http://www.mppng.nl/manifold/pointlabeler

tjhb
10,094 post(s)
#13-Aug-14 09:51

Not bad Chris.

Now add comments. (Especially for lines 4 and 8.)

*Much* less useful without.

atomek

422 post(s)
#15-Aug-14 12:46

Great, thank you!

And I would also appreciate comments on line 4 & 8

Sloots

678 post(s)
#18-Aug-14 15:30

The equation comes from the internet. I'm not a mathematician, so I leave the derivation to someone else, but I might shed some light on it.

First of all, a line can be written as y - y1 = (y2 - y1) / (x2 - x1) * (x - x1). the (y2 - y1) / (x2 - x1) part is the slope of the line, let's call it m. the slope of tyhe perpendicular line is -1 / m. And that line goes through point x3, y3 and the unknown intersection point x4, y4. Al we have to do is solve these two equations to find x4, y4.

That is what's happening here I believe.

Chris


http://www.mppng.nl/manifold/pointlabeler

atomek

422 post(s)
#18-Sep-14 11:47

Hi,

I'm having issues when the drawing is not in Orthographic projection.

The projection I'm working in is Transverse Mercator (Ordnance Survey Great Britain 1936 England) Center Lat 49, Center Lon -2.

Even if Line and Point are in Orthographic and query result is inserted into a Map with the projection in working in, the lines are not perpendicular. I know it's reprojection issue but is there a way to make it usable in real world situation as everyone is working in *some* specific projection.

Thanks,

Tom

tjhb
10,094 post(s)
#18-Sep-14 23:17

Good point. The query does not assign any projection to the geometry it creates (in the [perpendicular] column)--it should. It should also use an OPTIONS clause to specify the projection for linked drawings. Lastly it should not simply assume the source drawings [Line] and [Point] have the same coordinate system, but should project the source geometry in one drawing (e.g. [Point]) to the coordinate system of the other ([Line]) before extracting coordinates from both.

atomek

422 post(s)
#19-Sep-14 18:59

even if both [Line] and [Point] are in the same proj and there is this OPTIONS clause specifying the same proj for linked drawing I get the result drawn totally off. Is it because my drawings have local scales, offsets, scale corrections and false easting/northing (even though they are transfered to the resulting linked query)?

tjhb
10,094 post(s)
#20-Sep-14 02:02

If the projections match (in all details) then no, I think it is likely to be only the first issue, that the query does not assign any projection to the new geometry.

Try wrapping the NewLine() function in

AssignCoordSys(..., CoordSys("Line" AS COMPONENT)) 

oisink
370 post(s)
#30-Sep-14 14:06

Hi folks

Here's my version using vbscript.

It uses Application.ActiveWindow to get selected Line and Point, so no editing component names in SQL.

It seems to work fine if line and points are in same projection - I haven't looked at mixed projections!

Comments welcome

Oisin

Attachments:
PerpendicularLines.map

BerndD

162 post(s)
#30-Sep-14 19:00

Thanks. Runs like a charm.


Organizations that want to adapt to CHANGE are using products that can adapt.

www.yeymaps.io

tjhb
10,094 post(s)
#02-Oct-14 00:06

That is truly good. Beautiful comments, very (re)usable code.

oisink
370 post(s)
#02-Oct-14 09:06

Aw shucks *warm glow inside*

Manifold User Community Use Agreement Copyright (C) 2007-2021 Manifold Software Limited. All rights reserved.