<p>Given two vectors <strong>A</strong> and <strong>B</strong> which form the line segment <strong>L</strong> = A-B.
Furthermore given a view frustum <strong>F</strong> which is defined by its left, right, bottom, top, near and far planes.</p>

<p>How do I clip <strong>L</strong> against <strong>F</strong>? </p>

<p>That is, test for an intersection <em>and</em> where on L that intersection occurs?
(Keep in mind that a line segment can have <strong>more</strong> than one intersection with the frustum if it intersects two sides at a corner.)</p>

<p>If possible, provide a code example please (C++ or Python preferred).</p>

[{'answer_id': 77888, 'author': 'Sarien', 'author_id': 1994377, 'author_profile': 'https://Stackoverflow.com/users/1994377', 'pm_score': 2, 'selected': False, 'text': '<p>I don\'t want to get into writing code for this now but if I understand "frustum" correctly the following should work.</p>\n\n<ol>\n<li>Intersect the Line with all given planes</li>\n<li>If you have two intersections you\'re done.</li>\n<li>If you have only one intersection calculate the front plane and intersect.</li>\n<li>If you still have only one intersection calculate the back plane and intersect.</li>\n</ol>\n\n<p>But I may have completely misunderstood. In that case please elaborate :)</p>\n'}, {'answer_id': 90676, 'author': 'jasonmray', 'author_id': 17230, 'author_profile': 'https://Stackoverflow.com/users/17230', 'pm_score': 1, 'selected': False, 'text': '<p>Adding to what Corporal Touchy said above, you\'ll need to <a href="http://local.wasp.uwa.edu.au/~pbourke/geometry/planeline/" rel="nofollow noreferrer">know how to intersect a line segment with a plane</a>.  In the description on that page, u represents the parameter in the parametric definition of your line.  First, calculate u using one of the 2 methods described.  If the value of u falls in the range of 0.0 to 1.0, then the plane clips the line somewhere on your segment.  Plugging u back into your line equation gives you the point where that intersection occurs.</p>\n\n<p>Another approach is to find the <a href="http://mathworld.wolfram.com/Point-PlaneDistance.html" rel="nofollow noreferrer">directed distance</a> of each point to a plane.  If the distance of one point is positive and the other is negative, then they lie on opposite sides of the plane.  You then know which point is outside your frustum (based on which way your plane normal points).  Using this approach, finding the intersection point can be done faster by doing a linear interpolation based on the ratio of the directed distances.  E.g. if the distance of one point is +12 and the other is -12, you know the plane cuts the segment in half, and your u parameter is 0.5.</p>\n\n<p>Hope this helps.</p>\n'}, {'answer_id': 34960552, 'author': 'ideasman42', 'author_id': 432509, 'author_profile': 'https://Stackoverflow.com/users/432509', 'pm_score': 1, 'selected': False, 'text': '<p>First <a href="https://stackoverflow.com/a/34960913/432509">extract the planes from your view matrix</a>.</p>\n\n<p>Then use your points to define a vector and min/max as (0, 1), then iterate over the planes and intersect them with the segment, updating the min/max, bailing out early if the <code>min &gt; max</code>.</p>\n\n<p>Here\'s an example of a pure Python function, no external deps.</p>\n\n<pre class="lang-py prettyprint-override"><code>def clip_segment_v3_plane_n(p1, p2, planes):\n    """\n    - p1, p2: pair of 3d vectors defining a line segment.\n    - planes: a sequence of (4 floats): `(x, y, z, d)`.\n\n    Returns 2 vector triplets (the clipped segment)\n    or (None, None) then segment is entirely outside.\n    """\n    dp = sub_v3v3(p2, p1)\n\n    p1_fac = 0.0\n    p2_fac = 1.0\n\n    for p in planes:\n        div = dot_v3v3(p, dp)\n        if div != 0.0:\n            t = -plane_point_side_v3(p, p1)\n            if div &gt; 0.0:  # clip p1 lower bounds\n                if t &gt;= div:\n                    return None, None\n                if t &gt; 0.0:\n                    fac = (t / div)\n                    if fac &gt; p1_fac:\n                        p1_fac = fac\n                        if p1_fac &gt; p2_fac:\n                            return None, None\n            elif div &lt; 0.0:  # clip p2 upper bounds\n                if t &gt; 0.0:\n                    return None, None\n                if t &gt; div:\n                    fac = (t / div)\n                    if fac &lt; p2_fac:\n                        p2_fac = fac\n                        if p1_fac &gt; p2_fac:\n                            return None, None\n\n    p1_clip = add_v3v3(p1, mul_v3_fl(dp, p1_fac))\n    p2_clip = add_v3v3(p1, mul_v3_fl(dp, p2_fac))\n\n    return p1_clip, p2_clip\n\n\n# inline math library\ndef add_v3v3(v0, v1):\n    return (\n        v0[0] + v1[0],\n        v0[1] + v1[1],\n        v0[2] + v1[2],\n        )\n\ndef sub_v3v3(v0, v1):\n    return (\n        v0[0] - v1[0],\n        v0[1] - v1[1],\n        v0[2] - v1[2],\n        )\n\ndef dot_v3v3(v0, v1):\n    return (\n        (v0[0] * v1[0]) +\n        (v0[1] * v1[1]) +\n        (v0[2] * v1[2])\n        )\n\ndef mul_v3_fl(v0, f):\n    return (\n        v0[0] * f,\n        v0[1] * f,\n        v0[2] * f,\n        )\n\ndef plane_point_side_v3(p, v):\n    return dot_v3v3(p, v) + p[3]\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/77836', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/14157/']