制作 3D 阵列的 2D 横截面切片 [英] Making 2D cross-sectional slices of a 3D array

查看:34
本文介绍了制作 3D 阵列的 2D 横截面切片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试根据体积 CT 数据制作实时模拟超声图像.诀窍在于用户控制探头的位置,它定义了他们看到的平面.

到目前为止,我所做的是将来自所有 dicom 图像的像素数据读取到单个 3D 像素阵列中,现在我需要做的是在不同角度重新切割该 3D 阵列.对不起,如果下面的描述有点草率,但想象一个 3D 矩形框(比如 100 像素宽和深 [x,z],和 500 长 [y])和一个 2D观察平面"(比如 50 x 50 像素).假设观察平面的起始位置(原点定义为平面近边缘的中点 - [0,25])的原点为 [50,250,0](顶面的死点,向下看),从左到右定向并笔直向下刺穿矩形.因此,视图平面具有三个可以更改的参数 - 原点的位置、围绕垂直线的旋转(从原点到平面相对边缘上的相应点的线)和倾斜"(平面围绕与盒子相交的线旋转).因此用户可以更改这三个参数,输出是由视图平面接触"的像素构建的图像.

再次,如果描述草率,我很抱歉,但我是一名没有强大数学背景的医学生.任何帮助将不胜感激.

解决方案

我会写一条线的二维方程,求解 x 的每个值,并将结果 y 变量四舍五入到最接近的整数——昨天 Edje09

暂时坚持二维情况,您建议的方法有两个主要问题

  1. 如果线条比 1 的梯度更陡,则可能会遗漏一些像素.
  2. 舍入可以选择比您想要选择的像素高一个像素.

这显示了可能存在的问题和a>oln2D 案例的解决方案,然后可以为 3D 案例构建.

编辑经过进一步思考,我可能已经制作了一个 写的大纲3D 案例的解决方案 可以转化为算法,从而转化为代码.就我所知,我没有做任何检查,也不能保证它的正确性,但希望能让你更上一层楼.

添加编辑代码以下 Javascript 代码似乎可以满足您的要求.它很慢,因此您需要在单击 SET 后等待.此外,窗格"不会在视图之间清除,因此在重新填充窗格"之前您无法判断正在发生任何事情.我仅通过使用 2 个图像在 z 方向表示 100 个像素进行了测试.函数 getPixels 中的第一行代码处理这个限制,删除 z 方向上的完整图像集.我进行的测试相当肤浅,但似乎通过了.最好有全套图片.

我将 3D 阵列想象为后面的一系列 D 图像 image(0),沿 z 方向运行到前面的 image(D-1).每个图像在 x 方向上具有宽度 W,在 y 方向上具有高度 H.感谢您的挑战,我喜欢它.

指向所用图像的压缩文件夹的链接位于代码末尾.

<头><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><!--版权所有 (c) 2013 约翰·金特此授予任何人免费获得本软件和相关文档文件(软件")副本的许可,不受限制地处理本软件,包括但不限于使用、复制、修改、合并的权利、发布、分发、再许可和/或销售本软件的副本,并允许向其提供本软件的人员这样做,但须符合以下条件:上述版权声明和本许可声明应包含在本软件的所有副本或重要部分中.该软件按原样"提供,不提供任何形式的明示或暗示的保证,包括但不限于适销性、特定用途的适用性和不侵权的保证.在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任承担责任,无论是在合同诉讼、侵权行为或其他方面,由软件或软件的使用或使用或其他原因引起的或与之相关的软件.--><title>3D 切片器</title><style type="text/css">div, 画布, img {位置:绝对;}图片{顶部:0像素;左:0像素;可见性:隐藏;}输入 {文本对齐:右;}.看到{可见性:可见;}#canvas3D {左:10px;顶部:10px;可见性:隐藏;}#canvas2D {左:10px;顶部:50px;边框:1px纯黑色;}#框架 {左:650像素;顶部:10px;边框:1px纯黑色;背景颜色:#DDDDDD;宽度:600px;高度:600px;}#framehead {左:0像素;顶部:0像素;高度:25px;宽度:100%;边框底部:1px纯黑色;背景色:#999999;}#用户数据 {顶部:10px;左:10px;}#originins {顶部:10px;左:10px;宽度:260px;}#origintext {顶部:200px;左:10px;宽度:260px;}#origininput {顶部:225px;左:10px;宽度:260px;}#originlimits {顶部:250px;左:10px;宽度:260px;}#thetaimg {顶部:10px;左:225px;}#thetatext {顶部:200px;左:225px;宽度:260px;}#thetainput {顶部:225px;左:225px;宽度:260px;}#thetalimits {顶部:250px;左:225px;宽度:260px;}#psiimg {顶部:10px;左:440px;}#psitext {顶部:200px;左:440px;宽度:260px;}#psiinput {顶部:220px;左:440px;宽度:260px;}#psilimits {顶部:250px;左:440px;宽度:260px;}#setButton {顶部:310px;左:10px;宽度:260px;}#轴{顶部:350px;左:10px;}</风格><script type="text/javascript">//如果不存在,则向字符串添加修剪函数 - 从字符串的开头和结尾去除空格if(typeof String.prototype.trim !== 'function') {String.prototype.trim = function() {return this.replace(/^s+|s+$/g, '');}}//getElementById 的缩写函数函数 $(id) {返回 document.getElementById(id);}//代码中设置的3D像素数组的参数无功W=100;//数组x方向的宽度,必须是偶数无功D=100;//z方向的数组深度,必须是偶数无功H=500;//数组y方向的高度//矩形平面 PQRS 的参数,它将通过切片 3D 阵列来选择 2D 阵列的像素//PQRS 以这样一种方式移动,即 PQ 保持平行于 xz 平面,PS 保持平行于 yz 平面//这些参数在代码中设置无功L=50;//矩形PQ的长度无功B=50;//矩形PS的宽度//初始化可由用户更改的参数.var O=new Point(W/2,0,D/2);//O是PQ的中间var theta=0;//平面绕垂直轴旋转后旋转角度PQ通过O,必须在-PI/2和PI/2之间无功psi=0;//平面以PQ为轴旋转后旋转角度PS,必须在-PI/2和PI/2之间//画布变量var c3D, c2D;/*getPixel 从由一堆 D(用于深度)2D 图像形成的 3D 像素阵列中获取单个像素* 从 0 到 D-1 编号,0 是后面的图像.* 每个图像具有宽度 W 和高度 H 像素.* 0<=x<W,0<=y<H,0<=z<D* 每个图像都在画布 canvas3D 上** 在本次测试中,img0.jpg 将用于 img0.jpg 到 img49.jpg,而 img50.jpg 将用于 img50 到 img99*/函数 getPixel(x,y,z) {//只需要下面一行,因为只有两个图像 img0.jpg 和 img50.jpg 用于测试z=数学地板(z/50)*50;//如果在z方向使用了完整系列的图像,则删除上面的行this.ctx.drawImage($("i"+z),0,0);var imdata=this.ctx.getImageData(0,0,this.width,this.height);var col=4*(y*this.width+x);var pix=new Pixel();pix.red=imdata.data[col++];pix.green=imdata.data[col++];pix.blue=imdata.data[col++];pix.alpha=imdata.data[col];返回像素;}//像素对象函数像素(){this.red;this.green;this.blue;这个.alpha;}//点对象函数点(x,y,z){这个.x=x;this.y=y;这个.z=z;}函数 Point2D(a,d) {这.a=a;这.d=d;}函数 setValues() {c2D.ctx.clearRect(0,0,c2D.width,c2D.height);var Oobj=Ochecked($("Oin").value);如果(!Oobj.OK){$("Oin").style.backgroundColor="#F1B7B7";返回}$("Oin").style.backgroundColor="#FFFFFF";O = Oobj.point;var th=parseInt($("thetain").value.trim());如果(isNaN(th)){$("thetain").style.backgroundColor="#F1B7B7";返回}if(th<=-90 || th>90) {$("thetain").style.backgroundColor="#F1B7B7";返回}$("thetain").style.backgroundColor="#FFFFFF";theta=th*Math.PI/180;var si=parseInt($("psiin").value.trim());如果(isNaN(si)){$("psiin").style.backgroundColor="#F1B7B7";返回}if(si<=-90 || si>90) {$("psiin").style.backgroundColor="#F1B7B7";返回}$("psiin").style.backgroundColor="#FFFFFF";psi=si*Math.PI/180;打印窗格();}函数 Ochecked(Ovalue) {Ovalue=Ovalue.trim();var V=Ovalue.split(",");if(V.length!=3) {return {OK:false}};var x=parseInt(V[0].trim());var y=parseInt(V[1].trim());var z=parseInt(V[2].trim());if(isNaN(x) || isNaN(y) || isNaN(z)) {return {OK:false}};if(x<0 || x>=W) {return {OK:false}};if(y<0 || y>=H) {return {OK:false}};if(z<0 || z>=D) {return {OK:false}};p=新点(x,y,z);返回 {OK:true,point:p};}函数打印窗格(){var p = new Point(O.x-Math.round((L/2)*Math.cos(theta)),O.y,O.z - Math.round((L/2)*Math.sin(theta)));var q = new Point(O.x+Math.round((L/2)*Math.cos(theta)),Oy,Oz + Math.round((L/2)*Math.sin(theta)));var s = new Point(p.x,p.y+Math.round((B)*Math.cos(psi)),p.z + Math.round((B)*Math.sin(psi)));var n = new Point2D(q.x-p.x,q.z-p.z);var PQincVec=getIncVec(n.a,n.d);n = new Point2D(s.y-p.y,s.z-p.z);var PSincVec=getIncVec(n.a,n.d);var 像素,col;var PSpoint =new Point(p.x,p.y,p.z);//沿 PS 初始化的点从 P 开始var PQpoint;//沿平行于 PQ 的线的点的变量var imdata=c2D.ctx.getImageData(0,0,c2D.width,c2D.height);for(var ps=0;ps<PSincVec.length;ps++){//沿线递增PSPSpoint.y+=PSincVec[ps].a;PSpoint.z+=PSincVec[ps].d;PQpoint = new Point(PSpoint.x,PSpoint.y,PSpoint.z);//沿平行于 PQ 的线的点初始化为 PS 上的当前点for(var pq=0;pqMath.abs(d)) {var incVec=getIncs(a,Math.abs(d));}别的 {var incVec=getIncs(Math.abs(d),a);for(var i=0;i<incVec.length;i++) {r=incVec[i];t=r.a;r.a=r.d;r.d=t;}}如果(d<0){for(var i=0;i<incVec.length;i++) {incVec[i].d*=-1;}}返回 incVec;}函数 getIncs(a,d) {var p=new Point2D(0,0);var vec=[];vec.push(p);for(var i=0;i<a;i++){p=new Point2D(1,Math.floor((i+1)*d/a) - Math.floor(i*d/a));vec.push(p);}返回 vec;}函数主(){//为用户输入设置限制和值.$("Oin").value=O.x+","+O.y+","+O.z;$("thetain").value=theta;$("psiin").value=psi;$("originlimits").innerHTML="0&lt;= x &lt;"+W+"<br>0>0<= y &lt;"+H+"<br>0<= z &lt;"+D;//设置canvas3D,使像素可读c3D=$("canvas3D");c3D.width=W;c3D.height=H;c3D.ctx=c3D.getContext('2d');c3D.getPixel=getPixel;//设置canvas2D以便像素可设置c2D=$("canvas2D");c2D.width=L;c2D.高度=B;c2D.ctx=c2D.getContext('2d');c2D.initialise=初始化;$("隐藏").style.width=L+"px";$("隐藏").style.height=B+"px";}<body onload="main()"><!-- 3D 阵列的图像列表--><img id="i0" src="images/img0.jpg"><img id="i50" src="images/img50.jpg"><!-- 3D 阵列的图像列表结束--><canvas id="canvas3D"></canvas><div id="frame"><div id="framehead">&nbsp;&nbsp;&nbsp;切片窗格的视图</div><canvas id="canvas2D"></canvas>

<div id="用户数据"><div id="originins">以 x,y,z 格式输入 </br>例如40、27、83/div<div id="origintext">Origin O 的位置​​</div><div id="origininput"><input id="Oin"></div><div id="originlimits">limits</div><img class="seen" id="thetaimg" src="images/theta.png"><div id="thetatext">Theta 度数</div><div id="thetainput"><input id="thetain"></div><div id="thetalimits">-90 &lt;θ&lt;=90</div><img class="seen" id="psiimg" src="images/psi.jpg"><div id="psitext">以度为单位的 Psi</div><div id="psiinput"><input id="psiin"></div><div id="psilimits">-90 &lt;psi &lt;=90 </div><div id="setButton"><input type="button" value="SET" onclick="setValues()"></div><img class="seen" id="axes" src="images/axes.jpg">

<div id="msg"></div>

rela

I'm trying to make realtime mock-ultrasound images from volumetric CT data. The trick is that the user controls the position of the probe, which defines the plane they are seeing.

What I've done so far is read the pixel data from all the dicom images into a single 3D array of pixels, and now what I need to do is reslice that 3D array at different angles. Sorry if the following description comes off a little sloppy, but imagine a 3D rectangular box (say 100 pixels wide and deep [x,z], and 500 long [y]) and a 2D "viewing plane" (say 50 x 50 pixels). Say the starting position of the viewing plane (origin defined as the middle point at the close edge of the plane - [0,25]) is with the origin at [50,250,0] (dead center of the top surface, looking down), oriented left to right and piercing the rectangle straight down. Thus, the viewing plane has three parameters that can be changed - the location of the origin, the rotation around the vertical (the line running from the origin to the corresponding point on the opposite edge of the plane), and the "tilt" (rotation of the plane around the line where it intersects with the box). So the user can change those three parameters, and the output is an image built from the pixels "touched" by the viewing plane.

Again, I apologize if the description is sloppy, but I'm a med student without a strong mathematics background. Any help would be greatly appreciated.

解决方案

I would write the 2D equation for a line, solve for each value of x, and round the resulting y variable to the nearest integer– Edje09 yesterday

Sticking to the 2D case for the moment the method you suggest has two main issues

  1. If the line is steeper than gradient of 1 then some pixels can be missed.
  2. rounding can choose a pixel above the one you would want to choose.

This pdf shows the issues and a possible solution for the 2D case which can then be built on for the 3D case.

EDIT After further thought I may have produced an written pdf outline solution for the 3D case that can be turned into an algorithm and hence into code. This is as far as I have got I have done no checking and cannot guarentee its correctness but hopefully will take you a stage further.

EDIT CODE ADDED The following Javascript code seems to do what you require. It is quite slow so you need to wait after clicking SET. Also the 'pane' does not clear between views so you cannot tell anything is happening until the 'pane' is refilled. I have only tested by using 2 images to represent 100 pixels in the z direction. The first code line in the function getPixels deals with this limitation, remove for a full set of images in the z direction. The test I have carried out are fairly superficial but seem to pass OK. Better with a full set of images.

I have imagined the 3D array as a series of D images image(0) at the back running the z direction to image(D-1) at the front. Each image having width W in the x direction and height H in the y direction. Thanks for the challenge I enjoyed it.

Links to a zipped folder of images used is at end of code.

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--
Copyright (c)  2013   John King
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-->
<title>3D Slicer</title>
<style type="text/css">
    div, canvas, img {
        position: absolute;
    }

    img {
        top:0px;
        left:0px;
        visibility:hidden;
    }
    input {
        text-align: right;
    }
    .seen {
        visibility: visible;
    }   
    #canvas3D {
        left:10px;
        top:10px;
        visibility:hidden;
    }
    #canvas2D {
        left:10px;
        top:50px;
        border:1px solid black;
    }
    #frame {
        left:650px;
        top:10px;
        border:1px solid black;
        background-color: #DDDDDD;
        width:600px;
        height:600px;
    }
    #framehead {
        left:0px;
        top:0px;
        height:25px;
        width:100%;
        border-bottom: 1px solid black;
        background-color: #999999;
    }
    #userdata {
        top:10px;
        left:10px;
    }
    #originins {
        top:10px;
        left:10px;
        width:260px;
    }
    #origintext {
        top:200px;
        left:10px;
        width:260px;
    }
    #origininput {
        top:225px;
        left:10px;
        width:260px;        
    }
    #originlimits {
        top:250px;
        left:10px;
        width:260px;
    }
    #thetaimg {
        top:10px;
        left:225px;
    }
    #thetatext {
        top:200px;
        left:225px;
        width:260px;
    }
    #thetainput {
        top:225px;
        left:225px;
        width:260px;
    }
    #thetalimits {
        top:250px;
        left:225px;
        width:260px;
    }
    #psiimg {
        top:10px;
        left:440px;
    }
    #psitext {
        top:200px;
        left:440px;
        width:260px;
    }
    #psiinput {
        top:220px;
        left:440px;
        width:260px;
    }
    #psilimits {
        top:250px;
        left:440px;
        width:260px;
    }
    #setButton {
        top:310px;
        left:10px;
        width:260px;
    }
    #axes {
        top:350px;
        left:10px;
    }
</style>
<script type="text/javascript">

    //add a trim function to string if not present - strips white space from start and end of string
    if(typeof String.prototype.trim !== 'function') {
        String.prototype.trim = function() {
            return this.replace(/^s+|s+$/g, ''); 
        }
    }

    // abbreviation function for getElementById
    function $(id) {
      return document.getElementById(id);
    }

    //parameters for 3D array of pixels set in code
    var W=100; //width of array in x direction, must be even
    var D=100; //depth of array in z direction, must be even
    var H=500; //height of array in y direction

    //parameters for the rectangular plane PQRS that will select the pixels for a 2D array by slicing through the 3D array
    //PQRS moves in such a way that PQ remains parallel to xz plane and PS remains parallel to yz plane
    //these parameters set in code
    var L=50; //length of rectangle PQ
    var B=50; //breadth of rectangle PS

    //Initialisation of parameters that can be changed by the user.
    var O=new Point(W/2,0,D/2); //O is middle of PQ
    var theta=0; //angle PQ is rotated after plane is rotated about a vertical axis through O, must be between -PI/2 and PI/2
    var psi=0; //angle PS is rotated after plane is rotated about PQ as an axis, must be between -PI/2 and PI/2

    //variable for canvases
    var c3D, c2D;


    /*getPixel gets an individual pixel from the 3D array of pixels formed by a stack of D (for depth) 2D images
     * numbered from 0 to D-1, with 0 being the image at the back.
     * Each image having width W and height H pixels.
     * 0<= x <W, 0<= y <H,  0<= z <D
     * each image is on the canvas canvas3D
     * 
     * for this test img0.jpg will be used for img0.jpg to img49.jpg  and img50.jpg will be used for img50 to img99
     */
    function getPixel(x,y,z) {
        // line below only required because just two images img0.jpg and img50.jpg are used for testing
        z=Math.floor(z/50)*50;          
        //Remove above line if full series of images used in z direction
        this.ctx.drawImage($("i"+z),0,0);
        var imdata=this.ctx.getImageData(0,0,this.width,this.height);
        var col=4*(y*this.width+x);
        var pix=new Pixel();
        pix.red=imdata.data[col++];
        pix.green=imdata.data[col++];
        pix.blue=imdata.data[col++];
        pix.alpha=imdata.data[col];
        return pix;
    }

    //Pixel Object
    function Pixel() {
        this.red;
        this.green;
        this.blue;
        this.alpha;
    }

    //Point Object
    function Point(x,y,z) {
        this.x=x;
        this.y=y;
        this.z=z;
    }

    function Point2D(a,d) {
        this.a=a;
        this.d=d;
    }

    function setValues() {
        c2D.ctx.clearRect(0,0,c2D.width,c2D.height);
        var Oobj=Ochecked($("Oin").value);
        if(!Oobj.OK) {
            $("Oin").style.backgroundColor="#F1B7B7";
            return
        }
        $("Oin").style.backgroundColor="#FFFFFF";
        O=Oobj.point;
        var th=parseInt($("thetain").value.trim());
        if(isNaN(th)) {
            $("thetain").style.backgroundColor="#F1B7B7";
            return
        }
        if(th<=-90 || th>90) {
            $("thetain").style.backgroundColor="#F1B7B7";
            return
        }
        $("thetain").style.backgroundColor="#FFFFFF";
        theta=th*Math.PI/180;
        var si=parseInt($("psiin").value.trim());
        if(isNaN(si)) {
            $("psiin").style.backgroundColor="#F1B7B7";
            return
        }
        if(si<=-90 || si>90) {
            $("psiin").style.backgroundColor="#F1B7B7";
            return
        }
        $("psiin").style.backgroundColor="#FFFFFF";
        psi=si*Math.PI/180;
        printPane();
    }

    function Ochecked(Ovalue) {
        Ovalue=Ovalue.trim();
        var V=Ovalue.split(",");
        if(V.length!=3) {return {OK:false}};
        var x=parseInt(V[0].trim());
        var y=parseInt(V[1].trim());
        var z=parseInt(V[2].trim());
        if(isNaN(x) || isNaN(y) || isNaN(z))  {return {OK:false}};
        if(x<0 || x>=W) {return {OK:false}};
        if(y<0 || y>=H) {return {OK:false}};
        if(z<0 || z>=D) {return {OK:false}};
        p=new Point(x,y,z);
        return {OK:true,point:p};
    }

    function printPane(){
        var p = new Point(O.x-Math.round((L/2)*Math.cos(theta)),O.y,O.z - Math.round((L/2)*Math.sin(theta)));
        var q = new Point(O.x+Math.round((L/2)*Math.cos(theta)),O.y,O.z + Math.round((L/2)*Math.sin(theta)));
        var s = new Point(p.x,p.y+Math.round((B)*Math.cos(psi)),p.z + Math.round((B)*Math.sin(psi)));
        var n = new Point2D(q.x-p.x,q.z-p.z);       
        var PQincVec=getIncVec(n.a,n.d);
        n = new Point2D(s.y-p.y,s.z-p.z);       
        var PSincVec=getIncVec(n.a,n.d);
        var pixel,col;
        var PSpoint =new Point(p.x,p.y,p.z); // points along PS initialised to start at P
        var PQpoint; //variable for points along line parallel to PQ
        var imdata=c2D.ctx.getImageData(0,0,c2D.width,c2D.height);          
        for(var ps=0;ps<PSincVec.length;ps++) {
            //increment along line PS
            PSpoint.y+=PSincVec[ps].a;
            PSpoint.z+=PSincVec[ps].d;
            PQpoint =new Point(PSpoint.x,PSpoint.y,PSpoint.z); // points along line parallel to PQ initialised to current point on PS
            for(var pq=0;pq<PQincVec.length;pq++) {
                //increment along line PQ
                PQpoint.x+=PQincVec[pq].a;
                PQpoint.z+=PQincVec[pq].d;
                //check that PQpoint is inside 3D array
                if(0<=PQpoint.x && PQpoint.x<W && 0<=PQpoint.y && PQpoint.y<H && 0<=PQpoint.z && PQpoint.z<D) {
                    pixel=c3D.getPixel(PQpoint.x,PQpoint.y,PQpoint.z);
                    //write pixel from point along line parallel to PQ onto plane
                    col=4*(ps*c2D.width+pq);
                    imdata.data[col++]=pixel.red;
                    imdata.data[col++]=pixel.green;
                    imdata.data[col++]=pixel.blue;
                    imdata.data[col]=pixel.alpha;
                }               
            }
        }
        c2D.ctx.putImageData(imdata,0,0);
    }

    function getIncVec(a,d) {
        var r,t;
        if(a>Math.abs(d)) {
            var incVec=getIncs(a,Math.abs(d));
        }
        else {
            var incVec=getIncs(Math.abs(d),a);
            for(var i=0;i<incVec.length;i++) {
                r=incVec[i];
                t=r.a;
                r.a=r.d;
                r.d=t;
            }
        }
        if(d<0) {
            for(var i=0;i<incVec.length;i++) {
                incVec[i].d*=-1;
            }
        }
        return incVec;
    }

    function getIncs(a,d) {
        var p=new Point2D(0,0);
        var vec=[];
        vec.push(p);
        for(var i=0;i<a;i++) {
            p=new Point2D(1,Math.floor((i+1)*d/a) - Math.floor(i*d/a));
            vec.push(p);
        }
        return vec;
    }

    function main() {
        //set limits and values for user input.
        $("Oin").value=O.x+","+O.y+","+O.z;
        $("thetain").value=theta;
        $("psiin").value=psi;
        $("originlimits").innerHTML="0&lt;= x &lt;"+W+"<br>0&lt;= y &lt;"+H+"<br>0&lt;= z &lt;"+D;
        //set canvas3D so that pixels are readable
        c3D=$("canvas3D");
        c3D.width=W;
        c3D.height=H;
        c3D.ctx=c3D.getContext('2d');
        c3D.getPixel=getPixel;

        //set canvas2D so that pixels are settable
        c2D=$("canvas2D");
        c2D.width=L;
        c2D.height=B;
        c2D.ctx=c2D.getContext('2d');
        c2D.initialise=initialise;

        $("hide").style.width=L+"px";
        $("hide").style.height=B+"px";
    }
</script>
</head>
<body onload="main()">
    <!-- list of images for 3D array -->
    <img id="i0" src="images/img0.jpg">
    <img id="i50" src="images/img50.jpg">
    <!-- end of list of images for 3D array -->

    <canvas id="canvas3D"></canvas>
    <div id="frame">
        <div id="framehead">&nbsp;&nbsp;&nbsp;View of Slicing Pane</div>
        <canvas id="canvas2D"></canvas>
    </div>
    <div id="userdata">
        <div id="originins">Enter in form x,y,z </br> eg 40,27,83</div>
        <div id="origintext">Position for Origin O</div>
        <div id="origininput"><input id="Oin"></div>
        <div id="originlimits">limits</div>
        <img class="seen" id="thetaimg" src="images/theta.png">
        <div id="thetatext">Theta in degrees</div>
        <div id="thetainput"><input id="thetain"></div>
        <div id="thetalimits">-90 &lt; theta &lt;=90</div>
        <img class="seen" id="psiimg" src="images/psi.jpg">
        <div id="psitext">Psi in degrees</div>
        <div id="psiinput"><input id="psiin"></div>
        <div id="psilimits">-90 &lt; psi &lt;=90</div>
        <div id="setButton"><input type="button" value="SET" onclick="setValues()"></div>
        <img class="seen" id="axes" src="images/axes.jpg">
    </div>
<div id="msg"></div>    
</body>
</html>

images used in code

这篇关于制作 3D 阵列的 2D 横截面切片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆