| Bytes | Lang | Time | Link |
|---|---|---|---|
| nan | 250930T053908Z | Atitaya | |
| 095 | APLNARS | 250922T111203Z | Rosario |
| 086 | TSQL | 250922T150830Z | jdt |
| 141 | JavaScript Node.js | 230828T151700Z | Someone |
| 033 | Mathematica Wolfram Language | 230905T194421Z | dirvine |
| 033 | R | 230828T151609Z | Dominic |
| 009 | MATL | 230828T091104Z | Luis Men |
| 061 | Charcoal | 230828T090536Z | Neil |
| 032 | J | 230828T044641Z | Bubbler |
Volume from set mean bord 91536.bag Fred dream come!!/i
APL(NARS), 95 chars
{(A B C)←m←{∣<↑-/⍵}¨⍵[⍳2]⍵[1,3]⍵[2,3]⋄C=0:A⋄(C>∣<A B)∨B>∣<A C:A⌊B⋄C÷⍨2×{√×/(4⍴(+/⍵)÷2)-(0,⍵)}m}
Input a, b, c are 3 points of the plane each as array 2 numbers, output one number.
It would calculate the distance of the segment bc from the point a, that would be the min of A=distance(a,b), B=distance(a,c), if h (the height of the triangle abc for the base bc) is out the segment bc (or b≡c) else return h (that would be as value Area(abc triangle)x2/C where C=distance(b,c)).
I use the one possible false proposition: if abc is a right-angle triangle of ipotenuse ac than (ac)^2-(ab)^2=(bc)^2 and the h is inside the segment bc. If (ac)^2-(ab)^2>(bc)^2 than h is out the segment bc (so the distance is not h in that case).
N←{∣<↑-/⍵}
N calculate the distance of 2 input points, so that N a,b is |a-b|.
S←{√×/(4⍴(+/⍵)÷2)-(0,⍵)}
S would find the area, in a triangle note A B C sides lenght (using Erone formula).
∣<A B
it translate the cople of numbers A and B in one complex number A+JB and than find sqrt(A^2+B^2).
test:
f←{(A B C)←m←{∣<↑-/⍵}¨⍵[⍳2]⍵[1,3]⍵[2,3]⋄C=0:A⋄(C>∣<A B)∨B>∣<A C:A⌊B⋄C÷⍨2×{√×/(4⍴(+/⍵)÷2)-(0,⍵)}m}
f (0 2)(0 2)(9 9)
0
f (5,5)(10,0)(10,10)
5
f (5,5)(0,0)(10,0)
5
f (0,10)(0,0)(10,10)
7.071067812
f (10,0)(0,0)(10,10)
7.071067812
f (0,0)(2,2)(4,8)
2.828427125
f (0 2)(1 2)(0 2)
0
f (0 0)(3 0)(3 0)
3
f (3 0)(3 0)(3 0)
0
T-SQL, 86 bytes
CREATE FUNCTION f(@ geometry,@g geometry)RETURNS real BEGIN RETURN @.STDistance(@g)END
JavaScript (Node.js), 146 144 140 156 141 bytes
-2 bytes because of oversight noted by @noodleman
-4 bytes thanks to @TheThonnu's suggestion
+16 bytes because I noticed my own error with the solution
-15 bytes because I made another mistake, but found nice ways to golf
Algorithm somewhat yoinked from @Neil's Charcoal answer, though with a slightly different method for handling the "segment" of "line segment."
Version 4 (current, now has test cases!)
(a,b,c,d,e,f,S=Math.sqrt)=>((x,y,z)=>Math.min(S(2*(y+z)-x-(y-z)**2/x)/2||9,S(y),S(z)))((f-d)**2+(e-c)**2,(f-b)**2+(e-a)**2,(d-b)**2+(c-a)**2)
(a,b) is the point, (c,d) is vertex 1, (e,f) is vertex 2. Returns a float.
Old Versions
Version 3 (BROKEN, fixed segment bug)
(a,b,c,d,e,f,S=Math.sqrt)=>((x,y,z)=>Math.min(S((x+y+z)*(x+y-z)*(x-y+z)*(y+z-x))/2/x,y,z))(S((f-d)**2+(e-c)**2),S((f-b)**2+(e-a)**2),S((d-b)**2+(c-a)**2))
Version 2 (uses default arg instead of separate call) (INCORRECT—SEE COMMENTS)
(a,b,c,d,e,f,S=Math.sqrt)=>((x,y,z)=>S((x+y+z)*(x+y-z)*(x-y+z)*(y+z-x))/2/x)(S((f-d)**2+(e-c)**2),S((f-b)**2+(e-a)**2),S((d-b)**2+(c-a)**2))
Version 1 (original + oversight fix) (INCORRECT—SEE COMMENTS)
(S=>(a,b,c,d,e,f)=>((x,y,z)=>S((x+y+z)*(x+y-z)*(x-y+z)*(y+z-x))/2/x)(S((f-d)**2+(e-c)**2),S((f-b)**2+(e-a)**2),S((d-b)**2+(c-a)**2)))(Math.sqrt)
Mathematica (Wolfram Language) 33 bytes
RegionDistance[Line[{#2, #3}],#]&
This uses Mathematica built-ins, but this program has the benefit of working in any dimension. You could use Mathematica graphics options to see the computation graphically. The TIO link above has the last of the test cases, but in 3D instead of 2D!
R, 34 33 bytes
Edit: -1 byte thanks to Giuseppe
\(p,a,b)min(abs(p-seq(a,b,,1e4)))
Input point p and segment endpoints a and b as complex numbers.
Approach copied from Luis Mendo's answer: upvote that!
Accuracy can be improved by changing 1e4 to a higher value (for instance, 1e9 without increasing code-length), but as-is it's easily within the ±1 accuracy in the x,y-range of 0–127.
MATL, 9 bytes
9W&ZS-|X<
Supports two dimensions. Inputs are complex numbers: first the segment endpoints, then the other point.
Try at MATL it online! Or verify all test cases.
Explanation
9W % Push 9. Compute 2 raised to that number, that is, 512
&ZS % Implicit inputs: segment endpoints. Generate vector of 512 evenly
% spaced numbers in the range defined by the endpoints, including them
- % Implicit input: point. Subtract, element-wise
| % Absolute value of each entry
X< % Minimum. Implicit display
Charcoal, 65 61 bytes
UMθ₂ΣXE§θ⊕κ⁻λ§ιμ²≔§θ⁰η≔⎇η⊗∕₂Π⁻⊘Σθ⁺θ⟦⁰⟧η⌈θζI⎇›X⌈θ²⁺Xη²Xζ²⌊Φθκζ
Try it online! Link is to verbose version of code. Takes input as a list of the two vertices and the point. Explanation:
UMθ₂ΣXE§θ⊕κ⁻λ§ιμ²
Calculate the lengths of the sides of a triangle with the given points.
≔§θ⁰η
Get the base of the triangle separately.
≔⎇η⊗∕₂Π⁻⊘Σθ⁺θ⟦⁰⟧η⌈θζ
Unless the base is zero, divide the triangle's area by it and double the result, giving the altitude.
I⎇›X⌈θ²⁺Xη²Xζ²⌊Φθκζ
Determine whether the base of the triangle contains the foot, and if so, output the altitude, otherwise output the shorter of the other two sides.
58 54 bytes taking complex numbers as input:
UMθ↔⁻ι§θ⊕κ≔§θ⁰η≔⎇η⊗∕₂Π⁻⊘Σθ⁺θ⟦⁰⟧η⌈θζI⎇›X⌈θ²⁺Xη²Xζ²⌊Φθκζ
Attempt This Online! Link is to verbose version of code.
J, 32 bytes
[:(1#.&.:*:[-]*1<.0>.%. ::0)/-"1
Takes input as v1 f point ,: v2 (a vector v1 on the left side, and a two-row matrix containing point and v2 on the right side). Supports arbitrary dimensions.
The main approach is to translate v1 to origin and compute the vector component of point onto v2. When the value is clamped to the range [0, 1], that times v2 becomes the point on the line segment that is closest to point. Then we can compute the norm of the difference.
[:(1#.&.:*:[-]*1<.0>.%. ::0)/-"1 left: v1, right: point ,: v2
-"1 (point - v1) ,: (v2 - v1)
[:( )/ run dyadically with the two rows as two args:
%. ::0 vector component
1<.0>. clamp to [0,1]
[-]* get the distance vector
1#.&.:*: norm of the vector
::0 attached to %. handles the case of zero-length line segment (if it would throw an error, return 0 instead). &.:*: is a fancy way of saying "square something, do something on it, and take its square root".
J, 23 bytes
[:([|@-]*1<.0>.9 o.%)/-
Same algorithm, but takes a complex number for each vector instead, therefore supporting only two dimensions. %. is replaced with % (division) followed by 9 o. (extract real part). Norm is simply |.